Files
zpan/server/entry-node.ts
T
Jasper VanandBob 29102e623d feat: v2.6 Z6 — 6h background entitlement refresh (#345)
- Add server/services/licensing-refresh-runner.ts: shared runner with
  5-min dedup guard, structured INFO logs, and no-op for unbound state
- Add workers/scheduled.ts + export scheduled() in workers/bootstrap.ts
  for CF Workers cron (every 6 hours)
- Add [triggers] crons = ["0 */6 * * *"] to wrangler.toml
- Add setInterval refresh on boot in server/entry-node.ts with
  "licensing.refresh.scheduler.started interval=6h" log
- Add POST /api/licensing/refresh-cron?secret=... public endpoint
  (timing-safe secret comparison) for non-CF platforms
- Extract ZPAN_CLOUD_URL_DEFAULT to shared/constants.ts, replacing
  four duplicated literals
- Document REFRESH_CRON_SECRET + scheduler setup in all 5 non-CF
  deploy guides (vercel, netlify, aws-lambda, azure-functions, cloud-run)

Agent-Profile: https://agent-kanban.dev/agents/a6bb038c4226a87f

Co-authored-by: Bob <aibob@mails.agent-kanban.dev>
2026-04-24 08:22:10 -04:00

37 lines
1.4 KiB
TypeScript

import { serve } from '@hono/node-server'
import { serveStatic } from '@hono/node-server/serve-static'
import { Hono } from 'hono'
import { ZPAN_CLOUD_URL_DEFAULT } from '../shared/constants'
import { createBootstrap } from './bootstrap'
import { createLibsqlPlatform } from './platform/libsql'
import { createNodePlatform } from './platform/node'
import { runLicensingRefresh } from './services/licensing-refresh-runner'
const REFRESH_INTERVAL_MS = 6 * 60 * 60 * 1000 // 6 hours
const platform = process.env.TURSO_DATABASE_URL
? await createLibsqlPlatform({
TURSO_DATABASE_URL: process.env.TURSO_DATABASE_URL,
TURSO_AUTH_TOKEN: process.env.TURSO_AUTH_TOKEN,
})
: createNodePlatform()
const app = await createBootstrap(platform)
const server = new Hono()
server.route('/', app)
server.use('/*', serveStatic({ root: './dist' }))
server.get('/*', serveStatic({ root: './dist', path: 'index.html' }))
const port = Number(process.env.PORT) || 8222
console.log(`ZPan server running on http://localhost:${port}`)
serve({ fetch: server.fetch, port })
// Start licensing refresh background scheduler
const cloudBaseUrl = process.env.ZPAN_CLOUD_URL ?? ZPAN_CLOUD_URL_DEFAULT
console.log('licensing.refresh.scheduler.started interval=6h')
setInterval(() => {
// runLicensingRefresh handles all errors internally and never rejects.
void runLicensingRefresh(platform.db, cloudBaseUrl)
}, REFRESH_INTERVAL_MS)