Changelog

The latest features and improvements across ShipAny templates.

v1.0.7

Paid guest posts, appearance settings, user-center switches and a renewal fix

paymentadminuisecurity

  • Paid guest posts — outside authors write at /settings/guest-posts and pay to submit. Admins review at /admin/guest-posts: approve to publish on /blog, request changes (the author resubmits for free) or reject with a full refund. A public /guest-post page pitches it. Off by default; turn it on at Settings → Users → Guest Posts
  • Search-engine safe — guest posts carry a Sponsored label, every external link renders rel="sponsored nofollow" and gets UTM tags at render time. Authors pick their slug and can preview before publishing; word and link limits are checked the same way in the editor and on the server
  • Guest post packages live in code — prices and link limits are kind: 'guest_post' entries in src/config/pricing.ts, like the main plans. A new generic order.reference (<kind>:<id>) ties an order to the record it buys, so payment, publishing and refunds happen in one atomic write
  • Appearance settings — admins can pick light/dark, a color theme (Classic, Forest, Ocean, Violet, Sunset, Rose, Slate), font, font size and the sidebar layout at Settings → General → Appearance, and optionally let users choose their own theme color. Rendered on the server, so there is no flash. Off by default: the site keeps its look from code
  • User-center switches — credits, billing, payments, API keys and tickets can each be turned off at Settings → Users → User Features. Hidden pages redirect and their APIs refuse. Signup and role settings moved to the new Users tab
  • Dashboard polish — the sidebar shows your logo next to the toggle, and only the first nav group (plus the one you're in) starts expanded. Confirmations use a shared dialog instead of the browser's

  • Subscription renewals no longer skip credits — Stripe usually sends the subscription update before the renewal payment. When it did, the renewal was treated as already handled: the user was charged but got no renewal order or credits (Creem and PayPal went through the same path). Renewals are now claimed by a unique order number derived from the billing period, so event order doesn't matter
  • Dependency security upgrade — pnpm audit goes from 189 advisories to 2. drizzle-orm 0.45, latest TanStack Start/Router, Vite, nitro and wrangler (no major bumps), and Next.js is no longer installed as better-auth's unused peer
  • Separate dev sessions per project — several projects on localhost no longer sign each other out; the session cookie prefix comes from AUTH_COOKIE_PREFIX or, in dev, the app name. Production cookies are unchanged
  • Plausible's allowed script hosts are read at runtime (PLAUSIBLE_SCRIPT_HOSTS), so changing them needs no rebuild, and a rejected host no longer blocks saving the other analytics settings
  • Payment notifications show the correct list price when a coupon is applied at checkout. Bot messages now start with 【app name】, and checkout return URLs keep the buyer's language

  • AGENTS.md gains sections on guest posts, user-center switches and appearance; the design-theme skill knows about the color themes
  • New test suites: pnpm test:guest-posts and pnpm test:payment, including renewal events arriving in either order
  • Attribution: an X-Powered-By: ShipAny header and a generator meta tag. The "Built with ShipAny" footer badge is optional per the LICENSE and now matches your theme colors
  • The README was rewritten for ShipAny TanStack

  • Schema: one new table, guest_post, and one nullable column, order.reference. schema.ts isn't tracked by git, so copy them in, then migrate
  • New permissions: run pnpm admin:token sync-permissions to register admin.guest-posts.read, .review and .reject
  • Dependencies: run pnpm install. In your own server functions, rename .inputValidator() to .validator(); the old name no longer exists at runtime
  • API keys: the user-center API keys page is now off by default. Turn it on if your users rely on it
  • Missed renewals: if you ran recurring plans on the 2026-10-11 code, compare the provider's paid renewal invoices with your renew orders and grant any missing credits
  • The full checklist is the 2026-10-17 and 2026-10-28 entries in UPGRADING.md at the repo root
v1.0.6

User activity timeline, custom event reporting and admin password reset

adminanalyticsagent

  • User activity timeline — the user detail page shows everything a user did, in time order: sign-up, orders created and paid, subscriptions, credit grants and charges, AI generations that succeeded or failed, and tickets. It is built from existing tables, so history shows up as soon as you upgrade
  • Readable and clickable — oldest first by default, so it reads top to bottom as the user's path to paying; switch to newest first for recent activity. Each row opens its order, subscription, credit record or ticket. Events in the same instant follow the real flow (order → payment → subscription → credits)
  • Custom event reporting — register a kind in src/config/events.ts, then report it with recordEvent() on the server or track() in the browser, and it appears in the timeline. Three examples ship: plan picked (reported by the pricing table), paywall hit, and risk flag
  • Plug in your own tables — events your project already stores (a gift log, say) join the timeline through a loader in timeline-sources.ts, with an admin page to open on click
  • Set user passwords — "Set password" in the users list menu signs the user out everywhere and gives OAuth-only users an email/password login. It needs the dedicated admin.passwords.reset permission, can't target accounts above the caller, and is refused for agent keys
  • Agents can read a user's history — the new users_timeline operation lets an agent answer "how did this user convert, and where did they stall?"
  • The users list menu is wider so labels don't wrap; subscriptions and credits lists accept a search term from the URL

  • Reporting is in the rules and skills: AGENTS.md gains a "Product events" section. new-module, new-page and quick-start prompt agents to report events at paywalls and key actions, and shipany-admin shows how to investigate a user with the timeline
  • Safe by default: only kinds marked client-reportable can come from the browser; payment, risk and permission events are server-only. Browser reports require a signed-in user on your own pages, are rate-limited, and carry only a small flat detail
  • Tests for event reporting, timeline ordering and paging, and password reset

  • Schema: one new table, user_event; existing tables are unchanged. schema.ts isn't tracked by git, so copy the table into it, then migrate
  • New permission: run pnpm admin:token sync-permissions to register admin.passwords.reset
  • The full checklist is the 2026-10-12 entry in UPGRADING.md at the repo root
v1.0.5

Agent API, analytics, refunds, atomic writes on D1 and a security sweep

agentadminpaymentsecuritycloudflare

  • Agent API — create agent accounts on the new "Agent API" admin page, grant them roles, and issue sa_admin_ keys that can expire and are shown only once. Agents such as Claude Code and Codex run the admin console through a Skill or MCP. Every call is journaled for idempotency, and the Logs tab shows the calls per agent
  • Multi-site Skill client — one agent can manage several ShipAny sites, with each site's key kept in a private local file (mode 0600) and selected by project name
  • Analytics — overview KPIs (users, 30-day net revenue, active subscriptions, open tickets) and a cohort conversion funnel filterable by UTM, referrer and country. The new analytics_report operation lets agents write daily and weekly reports
  • Admin refunds for Stripe, Creem, PayPal, Alipay and WeChat Pay. A refund claws back the order's credits and can cancel the subscription. It needs the dedicated admin.payments.refund permission, which only super admins hold by default
  • User detail page with signup attribution (UTM, referrer, country), roles, and order and credit totals. The users list gains ID, effective-role and utm_source filter columns
  • Admin lists — payments, subscriptions, credits and tickets show users as avatar + name + email, linking to the detail page. Search is case-insensitive and matches email, name or user ID
  • Bot notifications for new orders and ticket activity via Telegram, Feishu, WeCom or a generic webhook
  • Cookie consent banner, enabled from admin settings, with a "Cookie settings" link in the footer
  • CNY pricing — products can set cnyPriceInCents, and Alipay and WeChat Pay charge that price

  • Payment notifications: on top of the signature check, Alipay and WeChat Pay notifications must match the configured app_id / merchant ID and the order amount, so another merchant's transaction can't settle your order
  • Credits are granted exactly once: settlement is guarded, and grants carry a per-order unique transaction number. The admin order edit can only close an unpaid order and can no longer move a paid order back to pending
  • No privilege escalation: role and permission assignment can't exceed the caller's own permissions, and an admin role can't be the default role for new users
  • Account takeover: with better-auth 1.7, OAuth sign-in no longer links to a password account whose email was never verified
  • Secret exfiltration: changing the OpenAI, Anthropic, R2, Telegram or webhook endpoint requires re-entering its secret
  • Script injection: analytics, ads and support-widget IDs are validated on save and on render. Plausible scripts load only from a same-site path, plausible.io, or hosts listed in the deployment env VITE_PLAUSIBLE_SCRIPT_HOSTS
  • Rate limits and uploads: limits are keyed by IP and user, so swapping cookies no longer bypasses them. Uploads are capped at 10 files and 20 MB per request, and SVG is refused
  • On Workers the client IP comes from the unspoofable cf-connecting-ip; seroval is pinned to 1.6.8

  • Atomic writes on D1: D1 has no interactive transactions, so db().transaction() ran statement by statement there. A failure halfway could leave a paid order without credits, or a half-charged balance. The new atomic() commits with a single batch() on D1, SQLite and Turso and uses a real transaction on Postgres and MySQL. Checkout settlement, renewals, refunds, credit charges and revokes, AI task creation and invite redemption all use it, with concurrency tests on local D1, SQLite and Postgres
  • No more USD amounts charged as CNY: Alipay and WeChat Pay refuse products that have no CNY price
  • Workers database connections: Postgres and MySQL get a client per request, and Hyperdrive query caching is off by default so order status, balances and settings are never up to 60 s stale
  • Deploy: compatibility_date is pinned, so builds no longer fail when local time is a day ahead of UTC
  • Successful checkout now lands on /settings/payments; subscription search, previously ignored by the API, now filters

  • AGENTS.md gains two sections. "Atomic writes" shows how to use atomic(). "Security & Integrity Rules" turns this round's findings into rules for new features: money, webhooks, permissions, secrets, rate limits and tests
  • New UPGRADING.md walks agents through pulling template updates into an existing project: port the schema, migrate, register new permissions, and the manual steps
  • New pnpm test:atomic, test:atomic:d1 and test:atomic:pg, plus regression tests for payments, refunds and permissions
  • pnpm admin:token CLI creates agents, issues keys and registers new permissions

  • Schema: additive only. schema.ts isn't tracked by git, so copy the new columns into it, then migrate
  • Alipay / WeChat Pay: set cnyPriceInCents on products, or those providers can't take orders
  • Self-hosted Plausible: if the script is a full URL on your own host, add that host to VITE_PLAUSIBLE_SCRIPT_HOSTS and rebuild (it is baked in at build time), or the script stops loading. Same-site proxy paths like /js/script.js are unaffected
  • New permissions: run pnpm admin:token sync-permissions
  • The full checklist is in UPGRADING.md at the repo root
v1.0.4

Webhook reliability, admin workflows, desktop auth hand-off

paymentauthadmindx

  • Admin workflows — order detail/edit dialog on the payments page, reworked users / roles / permissions screens, richer API keys management, ticket handling
  • Customer service widgets — Crisp and Tawk.to, toggled from admin settings
  • Cloudflare Email provider alongside Resend; auth emails now go through a provider-agnostic sender
  • Return-to-origin redirects — sign-in, Google One Tap, the support widget and checkout all bring the user back to the page they started from
  • Desktop hand-off — a new /auth-callback page hands a session token to app protocol URLs (myapp://…), limited to the schemes allow-listed in the new desktop_auth_schemes setting (empty by default)
  • Signup grants — the "grant credits on signup" toggle and the default role are finally applied to new users
  • /ads.txt route and AdSense support
  • AUTH_TRUSTED_ORIGINS accepts hostname-suffix wildcards (.e2b.app) for sandbox preview domains

  • Stripe webhooks on Cloudflare Workers: signature verification switched to constructEventAsync() — the sync call threw "SubtleCryptoProvider cannot be used in a synchronous context" and broke every event
  • Webhook failures return 500 so providers retry. They previously answered HTTP 200, so Stripe marked failed deliveries as succeeded and silently dropped renewals, periodic credits and subscription status syncs. Events the app doesn't handle are still acked with 2xx
  • Subscription renewals: renewal invoices are routed to the renewal handler instead of the first-purchase path, and deduped by provider + invoice ID
  • Admin settings: saved values take effect immediately (config cache refresh); the public config endpoint no longer returns secrets
  • Selects: a closed trigger shows the item label instead of the raw value
  • Docker build: reads .env.production and sets NODE_ENV in the builder stage so VITE_* vars get inlined
  • Dev server: allows e2b sandbox preview hosts

  • design-theme skill v2 — derives a distinctive visual identity from the project brief, with a 9-direction style library and an anti-slop checklist, so a new site never ships the stock look
  • Sandbox preview bridge — reports route changes and on-page links to the ShipAny Code parent frame
  • AGENTS.md: admin console hand-off, mandatory pnpm db:push after schema changes, Playwright/Chromium availability in the sandbox
v1.0.3

llms.txt, error pages, Creem mapping, email fix, Prettier

seouxpaymentauthdx

  • /llms.txt and /llms-full.txt routes — AI-readable site map, auto-generated from pages + blog posts
  • Styled error boundary in root route — "Oops" heading, retry button, dev-only error display (replaces TanStack Router default)
  • Creem Product IDs Mapping — admin setting to map internal product IDs to Creem prod_xxx IDs; auto-resolved during checkout

  • Email verification: public config API now supports Cloudflare Email provider for email_verification_enabled and password_reset_enabled
  • Sign-in: detects EMAIL_NOT_VERIFIED error code directly — always redirects to verify-email page
  • Verify-email Continue: shows toast instead of redirecting to sign-in when not yet verified

  • Prettier + husky + lint-staged — auto-format on commit
  • New scripts: pnpm format and pnpm format:check
  • Full codebase format pass applied
v1.0.2

OpenAI & Anthropic settings, custom configs, and login redirect

adminaiauth

  • Admin AI settings now include OpenAI and Anthropic providers (custom Base URL + API Key), each with a live Test that runs a real chat-completion check; Gemini card removed
  • Provider Test uses the values currently entered in the form — even unsaved — falling back to saved config (masked secrets left untouched)
  • New Custom settings tab — manage arbitrary key/value configs with add/remove rows
  • Auth: protected pages redirect to sign-in with a callbackUrl and send you back to the original page after login, preserved across the sign-in / sign-up switch

  • Turso: fixed drizzle.config.ts (turso dialect mapping + DATABASE_AUTH_TOKEN) so db:push / db:generate authenticate against the remote libsql database
v1.0.1

One-click deploy to Cloudflare Workers

cloudflaredeploy

  • One-click deploy to Cloudflare Workers (D1, or Postgres + Hyperdrive)
  • New deploy-cloudflare skill — handles D1, secrets, schema push and redeploy automatically
  • Fixed a number of SSR and hydration edge cases
v1.0.0

ShipAny TanStack first release

releasetanstack-start

The newest member of the ShipAny family — the full agent-native business engine, now on TanStack Start.

  • Brand-new template on TanStack Start (Vite 8 + Nitro + React 19, TypeScript strict)
  • File-based routing — no RSC, no "use client", all plain React components
  • TanStack Query / Form / Table throughout, backed by a typed api-client
  • Paraglide JS i18n — compiled, tree-shakeable message functions
  • better-auth + Drizzle ORM, sharing ShipAny's modular business logic (auth, credits, payments & subscriptions, API keys, RBAC)