Files
accounted/docker/crontab.hosted
T
Mattsson e113e9c099 fix(vat,documents): EU reverse-charge packs feed ruta 20/21; daily reanchor cron for floating supplier-invoice underlag (#2095)
Two user reports (Anders, 2026-08-25 + 2026-08-29):

1. The seeded standardmallar "Inkop EU-varor/-tjanster, omvand moms 25%"
   booked the cost on 4010/6540, which no momsdeklaration ruta reads, so the
   fiktiv moms filled ruta 30/48 while ruta 20/21 (inkopsvarde) stayed 0;
   Skatteverket rejects that (FK004, ML 13 kap). The packs now book directly
   on the basis accounts 4515/4535 (ACCOUNT_RUTA -> ruta 20/21); the
   transaction-picker path already skips its own basis emission for basis
   debit accounts, so no double counting. Regression test pins every
   reverse-charge pack to a 44xx/45xx business debit. Prod rows update via
   the existing pack sync cron (upsert on pack_slug).

2. A kontantmetod payment verifikat stayed "Underlag saknas" although the
   invoice PDF was attached and eligible on every static condition: the
   inline anchorSupplierInvoiceDocument silently did nothing (prod case
   2026-08-28, verified in audit_log: no document_attachments update between
   the payment booking and the user's manual re-upload). The helper now
   verifies the guarded update actually matched a row instead of claiming
   success on zero rows, logs its silent bail branches, and a new daily cron
   (/api/documents/reanchor/cron) re-runs the anchor for any floating
   retained document with a posted verifikat, replacing the pattern of
   one-off repair migrations (20260727180000, 20260824150000). The sweep
   names the FK in its embed and is idempotent; locked/closed periods are
   skipped as before.


Claude-Session: https://claude.ai/code/session_01Jj6Rg1ViyFRej55gbxLVgj

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-09-01 10:16:07 +02:00

54 lines
4.5 KiB
Plaintext

# AUTO-GENERATED: do not edit. Run `npm run crontabs:generate` to regenerate.
#
# Variant: hosted (bind-mounted by docker-compose.hosted.yml).
# Source of truth: the `crons` array in vercel.json. Paths, order and
# cadence mirror it exactly; scripts/__tests__/generate-crontabs.test.ts
# fails CI if this file drifts from it.
#
# Consumed by supercronic (docker/cron.Dockerfile), bind-mounted read-only
# at /etc/supercronic/crontab. Times are UTC: the cron container sets no TZ
# and Alpine defaults to UTC, same as Vercel Cron. supercronic skips a tick
# whose previous run is still going (overlapping is off by default), so a
# slow endpoint cannot pile up.
#
# Extension endpoints are listed unconditionally, including extensions this
# image's preset does not enable. Each answers 200 with a no-op body when
# its extension is unconfigured, so an unused one costs a single cheap
# request, and enabling it later needs no crontab change.
#
# Load note: /api/webhooks/dispatch/cron runs every minute, 1440 requests a
# day. Each tick is one indexed query that returns immediately when no
# delivery is due, and the per-minute cadence is what makes the dispatcher
# 60-second first retry actually happen after 60 seconds. Change it only
# through SCHEDULE_OVERRIDES in scripts/generate-crontabs.ts, never by
# editing this file.
0 6 * * * curl -sf -H "Authorization: Bearer ${CRON_SECRET}" ${APP_URL}/api/deadlines/status/cron
0 * * * * curl -sf -H "Authorization: Bearer ${CRON_SECRET}" ${APP_URL}/api/invoices/recurring/cron
30 4 * * * curl -sf -H "Authorization: Bearer ${CRON_SECRET}" ${APP_URL}/api/settings/booking-templates/sync/cron
0 0 * * * curl -sf -H "Authorization: Bearer ${CRON_SECRET}" ${APP_URL}/api/tax-deadlines/cron
0 5 * * * curl -sf -H "Authorization: Bearer ${CRON_SECRET}" ${APP_URL}/api/extensions/enable-banking/sync/cron
30 3 * * * curl -sf -H "Authorization: Bearer ${CRON_SECRET}" ${APP_URL}/api/extensions/stripe/transactions/cron
45 3 * * * curl -sf -H "Authorization: Bearer ${CRON_SECRET}" ${APP_URL}/api/extensions/woocommerce/orders/cron
15 3 * * * curl -sf -H "Authorization: Bearer ${CRON_SECRET}" ${APP_URL}/api/extensions/shopify/orders/cron
0 3 * * * curl -sf -H "Authorization: Bearer ${CRON_SECRET}" ${APP_URL}/api/documents/verify/cron
30 3 * * * curl -sf -H "Authorization: Bearer ${CRON_SECRET}" ${APP_URL}/api/documents/reanchor/cron
0 4 * * * curl -sf -H "Authorization: Bearer ${CRON_SECRET}" ${APP_URL}/api/sandbox/cleanup/cron
0 2 * * * curl -sf -H "Authorization: Bearer ${CRON_SECRET}" ${APP_URL}/api/events/cleanup/cron
0 * * * * curl -sf -H "Authorization: Bearer ${CRON_SECRET}" ${APP_URL}/api/extensions/cloud-backup/auto-sync/cron
30 * * * * curl -sf -H "Authorization: Bearer ${CRON_SECRET}" ${APP_URL}/api/idempotency/cleanup/cron
30 2 * * * curl -sf -H "Authorization: Bearer ${CRON_SECRET}" ${APP_URL}/api/pending-operations/expire/cron
0 4 * * * curl -sf -H "Authorization: Bearer ${CRON_SECRET}" ${APP_URL}/api/extensions/skatteverket/skattekonto/sync/cron
*/15 * * * * curl -sf -H "Authorization: Bearer ${CRON_SECRET}" ${APP_URL}/api/extensions/skatteverket/agi/kvittenser/cron
30 */2 * * * curl -sf -H "Authorization: Bearer ${CRON_SECRET}" ${APP_URL}/api/extensions/skatteverket/vat/kvittenser/cron
* * * * * curl -sf -H "Authorization: Bearer ${CRON_SECRET}" ${APP_URL}/api/webhooks/dispatch/cron
* * * * * curl -sf -H "Authorization: Bearer ${CRON_SECRET}" ${APP_URL}/api/extensions/whatsapp-inbox/sweep/cron
15 4 * * * curl -sf -H "Authorization: Bearer ${CRON_SECRET}" ${APP_URL}/api/extensions/whatsapp-inbox/retention/cron
*/2 * * * * curl -sf -H "Authorization: Bearer ${CRON_SECRET}" ${APP_URL}/api/extensions/invoice-inbox/sweep/cron
45 5 * * * curl -sf -H "Authorization: Bearer ${CRON_SECRET}" ${APP_URL}/api/extensions/invoice-inbox/underlag-reconcile/cron
15 5 * * * curl -sf -H "Authorization: Bearer ${CRON_SECRET}" ${APP_URL}/api/bookkeeping/accruals/post-due/cron
30 5 * * * curl -sf -H "Authorization: Bearer ${CRON_SECRET}" ${APP_URL}/api/receipt-hunt/cron
45 5 * * * curl -sf -H "Authorization: Bearer ${CRON_SECRET}" ${APP_URL}/api/notifications/bookkeeping-digest/cron
*/10 * * * * curl -sf -H "Authorization: Bearer ${CRON_SECRET}" ${APP_URL}/api/peppol/inbound/cron
5,20,35,50 * * * * curl -sf -H "Authorization: Bearer ${CRON_SECRET}" ${APP_URL}/api/peppol/outbound/status/cron