38 Commits
Author SHA1 Message Date
saltbo 15698aabab ci(release): guide developer to pnpm release on version mismatch 2026-06-09 15:21:59 -04:00
saltboandClaude Opus 4.8 e700fd4977 feat(about): add changelog drawer, latest-version check, and commit hash
Maintain a CHANGELOG.md (Keep a Changelog format) at the repo root and surface
it on the admin About page:

- The page now shows the running build's short commit hash next to the version,
  linked to the GitHub commit. Commit is injected at build time via a new
  resolveAppCommit() (ZPAN_APP_COMMIT -> WORKERS_CI_COMMIT_SHA -> git rev-parse),
  wired through vite/tsup defines, the node entry, Docker, and CI.
- A new admin-only GET /api/system/changelog endpoint fetches CHANGELOG.md from
  master on GitHub, caches it, parses the latest released version, and reports
  whether an update is available (semver compare against the running version).
- The About page renders a "latest version" row with an update-available badge
  and a side drawer that displays the changelog markdown.

Tests cover the semver compare, changelog parse/fetch caching, the API wrapper,
and the route (admin-gated, parsed payload).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-09 13:38:29 -04:00
saltboandClaude Opus 4.8 42342be665 fix(version): resolve app version from package.json, not git describe
Cloudflare Workers Builds deploys master continuously without setting
ZPAN_APP_VERSION, and its checkout has no tags, so git describe --always fell
back to a bare commit hash — the deployed Worker showed a commit instead of a
version. package.json is present in every build environment, so read the
version from it when ZPAN_APP_VERSION is unset. Release/Docker/GH-action
deploys still pass the exact tag via the env var, which keeps priority.

Release process: bump package.json on each release so Workers Builds reports
the right version.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-09 11:36:15 -04:00
saltboandClaude Opus 4.8 0063557d09 fix(docker): repair image startup and guard it in CI
The bundled app-version.mjs self-exec block (`import.meta.url ===
file://${process.argv[1]}`) fired at runtime once tsup inlined it into
entry-node.js, since the container runs `node dist-server/entry-node.js`.
It shelled out to `git describe`, which is absent in the image, crashing
the server on boot and leaving the compose stack unhealthy. Drop the
unused CLI entry; resolveAppVersion is still build-time inlined.

Also stop the CLI build from overwriting the `latest` tag: metadata-action
defaults to latest=auto, so cli-meta re-added a bare `latest` that, running
after the server build, clobbered it with the downloader image. Pin
latest=false on cli-meta.

Add a docker-smoke CI job that runs `docker compose up --wait` so an image
that fails to boot turns CI red, and give the GeoIP download --retry to cut
flake on that external fetch.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-09 10:51:13 -04:00
Jasper VanandClaude Opus 4.8 af43701daf fix(version): set app version global in node entry (#418)
* fix(version): resolve app version at runtime in node entry

E2E runs the Node server via tsx, which bypasses the tsup build-time
define, leaving __ZPAN_APP_VERSION__ unset so getAppVersion throws and
/api/licensing/pair returns 500. Resolve the version at runtime via
resolveAppVersion (git describe) when the global is unset; in the built
output the define inlines the constant, so the branch is never reached
and git is not invoked in production. Keeps the git-describe version as
the single source of truth across all paths.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(version): inject app version into docker build

The Docker build excludes .git from its context (.dockerignore), so the
build-time git describe in build:node would throw and break the image
build. Let resolveAppVersion read ZPAN_APP_VERSION, set it from an
APP_VERSION build arg in the builder stage, and pass the release tag from
the release workflow. git describe stays the default everywhere else, so
the version is unified across CF Workers, tsx, and Docker.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 19:29:47 -04:00
saltbo 43e92caaa6 chore(config): consolidate project tooling 2026-06-08 15:17:54 -04:00
saltbo 3b5f6c7fb5 fix(telemetry): persist detected site origin 2026-06-08 14:43:34 -04:00
saltbo 6bcb540d05 fix(telemetry): do not fail deploy on report timeout 2026-06-08 14:11:39 -04:00
saltbo 61f643ae18 fix(telemetry): clean up deploy report secret 2026-06-08 13:07:02 -04:00
Jasper Van bd9f047ebb fix(telemetry): report instance after deployment (#417) 2026-06-08 12:40:59 -04:00
Jasper Van ac00164fb4 ci(e2e): run core checks before cloud store flow
ci(e2e): run core checks before cloud store flow
2026-06-08 10:55:11 -04:00
Jasper Van 9d70acfdea feat(licensing): support independent business authorization
Support independent Pro and Business licensing, migrate Cloud store integration through the SDK, gate Business-only credit billing features, and validate the Cloud store E2E flow.
2026-06-08 01:42:23 -04:00
saltbo bc3ef9f512 fix(downloads): use standard geoip data paths 2026-06-06 09:52:07 -04:00
saltbo 12604529b1 feat(downloads): report peer geo regions 2026-06-06 09:44:36 -04:00
saltbo f31278b434 refactor(cli): move zpan command module to cmd 2026-06-06 01:49:41 -04:00
saltbo 3f7a859e73 refactor(downloader): consolidate api contract generation 2026-06-05 15:24:56 -04:00
saltbo 086319da69 test: harden cloud e2e tunnel handling 2026-06-03 14:19:17 -04:00
saltbo 87b40bb8ef test: stabilize cloud e2e auth flow 2026-06-03 03:10:44 -04:00
saltbo 53076d7873 feat(downloads): add remote download workers 2026-06-03 02:21:50 -04:00
saltbo cf12806902 fix(e2e): clean cloud license slots 2026-06-02 22:52:14 -04:00
saltbo 4a54f2dfa3 fix(e2e): stabilize cloud pairing slots 2026-06-02 22:41:00 -04:00
saltbo 30bc6e1a12 build: migrate project to pnpm 2026-06-01 10:44:33 -04:00
saltbo 2438275ea8 feat(archive): queue streaming archive jobs 2026-05-15 09:59:08 -04:00
saltbo ab9014133f test(e2e): isolate cloud runtime ports 2026-05-10 12:19:09 -04:00
saltbo 73a592c8d9 feat(pro): tighten gates and unify upgrade prompts 2026-05-10 01:58:49 -04:00
saltbo 800cda9f9c test(cloud): add tunnel-backed store e2e 2026-05-09 22:17:52 -04:00
saltboandCopilot 0137f009d4 feat(docker): add deploy variants and auto-generate auth secret
- Add --external better-sqlite3 to tsup build to fix ESM runtime error
- Add docker-entrypoint.sh to auto-generate BETTER_AUTH_SECRET if not set
- Persist generated secret to /data/.auth_secret across restarts
- Move image-based compose files to deploy/ directory
- Add deploy/docker-compose.rustfs.yml for ZPan + RustFS setup
- Keep build-from-source docker-compose.yml at project root

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-21 10:41:24 -04:00
saltboandClaude Opus 4.6 6c8f042948 feat: auto-configure GitHub OAuth in db-reset seed script
Reads GITHUB_CLIENT_ID and GITHUB_CLIENT_SECRET from .dev.vars
and inserts the OAuth provider config into system_options during
database reset, so GitHub login works out of the box locally.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 15:27:32 -04:00
4a5fbb7f4a feat(auth): add dynamic OAuth provider system (#282)
* feat(auth): add dynamic OAuth provider system

Admin can configure OAuth/OIDC providers in the database via API.
All 35 built-in better-auth providers are registered as async functions
that read config from system_options at runtime. Custom OIDC providers
use the genericOAuth plugin with configs loaded at auth init time.

New endpoints:
- GET /api/auth-providers (public, enabled only, no secrets)
- GET /api/auth-providers/admin (admin, all configs, masked secrets)
- PUT /api/auth-providers/admin/:providerId (admin, upsert)
- DELETE /api/auth-providers/admin/:providerId (admin, remove)

Agent-Profile: https://agent-kanban.dev/agents/a6bb038c4226a87f
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: async createTestApp compat in email and invite test files

createAuth became async in the OAuth PR, which made createTestApp async.
Email and invite code test files need await + Awaited<> type wrappers.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Bob <aibob@mails.agent-kanban.dev>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-12 21:46:11 -04:00
saltboandClaude Opus 4.6 33ca372bdb fix(dev): fix D1 local database name and add db:migrate:d1 script
db-reset.ts referenced non-existent 'zpan-db-local'; update to
'zpan-db-staging' with --env staging to match wrangler.toml. Add
npm run db:migrate:d1 shortcut and update CONTRIBUTING.md.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 14:50:13 -04:00
Jasper VanandBob 689d9cc74f refactor: remove custom filePath, enforce tenant-isolated storage path (#278)
* refactor: remove custom filePath, enforce tenant-isolated storage path

Replace user-customizable filePath template with a hardcoded
tenant-isolated pattern ($ORG_ID/$UID/$NOW_DATE/$RAND_16KEY$RAW_EXT).
This ensures proper tenant isolation and removes unnecessary complexity.
The DB column is preserved to avoid migration; code simply stops
reading/writing it.

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

* refactor: clean up dead tokens, locale keys, and simplify path template

Remove unused template tokens ($UUID, $RAW_NAME, $NOW_YEAR, $NOW_MONTH,
$NOW_DAY) and corresponding TemplateVars fields (uuid, rawName) since
the hardcoded template doesn't use them. Remove orphaned i18n keys for
fieldFilePath. Update DB schema default to empty string. Add storage
service unit tests.

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

---------

Co-authored-by: Bob <aibob@mails.agent-kanban.dev>
2026-04-12 14:09:29 -04:00
saltboandClaude Opus 4.6 877ef9d212 refactor(deploy): inline staging env detection into npm build script
Move CLOUDFLARE_ENV logic from ci-build.sh into package.json build
script. Workers Builds can use default build command (npm run build)
without custom Dashboard configuration.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 13:14:23 -04:00
saltboandClaude Opus 4.6 abba373dcc feat(deploy): auto-select staging env for non-production branch builds
Add ci-build.sh that checks WORKERS_CI_BRANCH to set CLOUDFLARE_ENV.
Non-master branches automatically build with staging config (staging D1).

Workers Builds Dashboard config:
- Build command: sh scripts/ci-build.sh
- Deploy command: npx wrangler deploy
- Version command: npx wrangler versions upload

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 13:12:50 -04:00
saltboandClaude Opus 4.6 3b80eff413 feat: migrate from CF Pages to Workers with one-click deploy button
- Replace Pages Functions with Workers entry (`workers/bootstrap.ts`)
- Add Deploy to Cloudflare button in README
- Integrate `@cloudflare/vite-plugin` for CF dev with HMR
- Integrate `@hono/vite-dev-server` for Node dev with HMR
- `npm run dev` now defaults to CF Workers mode
- Add `run_worker_first = ["/api/*"]` so static assets stay free
- Extract shared Node bootstrap (`server/bootstrap.ts`) for reuse
- Update all docs from Pages to Workers references

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 10:40:15 -04:00
saltboandClaude Opus 4.6 3d14f3ceae chore(dev): enhance db:reset for D1 local and add top-level D1 binding
- db:reset script supports --pages flag to reset D1 local database
- Added db:reset:pages npm script
- Added top-level D1 binding in wrangler.toml for local dev
- Standardized dev env var names in .dev.vars

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 23:52:24 -04:00
saltboandClaude Opus 4.6 bce4da3ebf feat(quota): add default org quota with admin settings UI and db:reset script
New users get a 10MB default storage quota (configurable via admin settings).
Admin can set the default in Settings with MB/GB unit selector. Added db:generate,
db:migrate, and db:reset scripts; dev server now reads .dev.vars automatically.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 23:37:54 -04:00
saltbo ff286a824d feat: update the code by the goproject template 2020-08-07 00:33:37 +08:00
saltbo 99d6e46a42 chore: add scripts to build and release 2019-10-27 11:29:04 +08:00