Commit Graph
19 Commits
Author SHA1 Message Date
Hanzo Dev a955a8201c ci(cicd): neutralize — build+deploy moved to native .hanzo/workflows/deploy.yml; GitHub is a mirror 2026-07-24 15:13:44 -07:00
Hanzo Dev df39da7476 ci(deploy): native Hanzo pipeline — buildkit → ghcr.io/hanzoai/cms:<sha> → operator patch app cms 2026-07-24 15:13:29 -07:00
hanzo-dev d04c1bc000 ci: pin hanzoai/ci@v1 (canonical stable alias) 2026-07-18 08:53:15 -07:00
hanzo-dev a2fe39ad36 fix(cms/admin): restore login form — IAM-only had no browser sign-in
The admin login rendered only the logo: Users.disableLocalStrategy hid the
email/password form (LoginView gates <LoginForm> on !disableLocalStrategy) and
no beforeLogin/SSO component or OIDC callback was ever wired, so there was no
way to sign in — the panel was a dead end (not a client mount hang).

Re-enable the local (email/password) strategy so the form renders; the IAM
bearer/JWKS strategy stays layered on top for SSO/API. email now comes from the
local strategy (dropped the duplicate from iamAuthFields). prodMigrations adds
the local-auth columns (salt/hash/reset*/login_attempts/lock_until) + the
users_sessions table on boot. The seeded z@<domain> superuser signs in with a
framework-hashed password.
2026-07-14 23:12:10 -07:00
hanzo-dev 769d708195 fix(cms/admin): regenerate importMap + generate it in build (blank-admin)
The committed importMap.js held ONE entry (CollectionCards) — it was never
generated against the real config, so every plugin client component was absent:
the entire lexical editor (20), the multi-tenant admin UI (5), and the S3 upload
handler. At runtime the admin RootProvider could not resolve those client
references, so it rendered an empty tree — a BLANK white page on ALL routes
including /admin/login (RSC flight streamed, client never committed, zero console
errors). Pod logs: "getFromImportMap: CMSComponent not found ...
@hanzo/cms-storage-s3/client#S3ClientUploadHandler ... run generate:importmap".

Fix: regenerate importMap.js (6 -> 64 lines, all client comps) AND wire
`hanzo-cms generate:importmap` into the app build so it can never drift from the
config again. Also corrects generate:types/importmap to the real CLI bin
(hanzo-cms; the fork has no `payload` bin — the old script was a latent ENOENT).
Build green; regeneration is idempotent ("No new imports found").

Claude-Session: https://claude.ai/code/session_01Gq8suw7uuodAMPDRpo6iAB
2026-07-14 18:01:02 -07:00
hanzo-dev d14e5c9309 feat(cms/pages): public read for PUBLISHED docs (headless storefront)
Pages.access.read now returns {_status: published} for anonymous requests
and true for authenticated callers. The multi-tenant plugin composes this
(withTenantAccess): a logged-in caller stays org-scoped; an anonymous caller
has no user, so no tenant constraint is added and published docs of ANY tenant
are world-readable — correct for a headless CMS serving many brands' storefronts
(karma.style/journal fetches with no token). Drafts and every write stay gated
exactly as 3.86.1.

proof.ts step 4b: anon read sees published, hides drafts (+ by-id negative
control). Verified on fresh SQLite: publicRead=true.

Claude-Session: https://claude.ai/code/session_01Gq8suw7uuodAMPDRpo6iAB
2026-07-14 17:51:11 -07:00
hanzo-dev 40f7026ff3 fix(auth-iam): project isAdmin+groups claims; admin all-tenant write gate
IAM admins have owner != "admin", so the multi-tenant all-tenants gate
(iamOrg === 'admin') matched nobody and every write 403'd. Project the
verified isAdmin (and groups) claims onto the CMS user and honor isAdmin
in the gate.

- strategy: map claims.isAdmin -> user.isAdmin, claims.groups -> user.groups
- iamAuthFields: add isAdmin (checkbox) + groups (json) so Payload persists
  and refreshes them on each SSO login
- types: IAMClaims gains isAdmin, groups
- demo payload.config: userHasAccessToAllTenants also honors user.isAdmin
- auth-iam 1.0.0 -> 1.0.1

Claude-Session: https://claude.ai/code/session_01Gq8suw7uuodAMPDRpo6iAB
2026-07-14 17:00:18 -07:00
hanzo-dev 703459d9af fix(releaser): publishList — drop nonexistent payload-cloud/plugin-stripe, add auth-iam+plugin-whitelabel 2026-07-13 10:40:36 -07:00
hanzo-dev 069e8537b2 fix(cms/docker): drop COPY of nonexistent public/ dir (media is on S3) 2026-07-13 08:01:48 -07:00
hanzo-dev 73c2e7de40 fix(cms/docker): build only the app graph (turbo --filter), not build:all
pnpm build:all built 44/46 in Docker but failed on @tools/scripts (unrelated
tooling not needed for the runtime image). Use the validated-green command
'pnpm turbo build --filter @hanzo/cms-demo' — builds the app + its real deps,
emits the standalone bundle, skips the tooling packages.
2026-07-12 22:37:30 -07:00
hanzo-dev 818adc3a58 build(cms): use hardened ci ref (sudo-free provision) until v1 adopts it 2026-07-12 22:19:11 -07:00
hanzo-dev a20f8775d6 Merge rename/payload-to-cms: full Payload→CMS rename + green build + image pipeline
Go-live merge — the complete de-brand (44 packages, build-verified green), the
demo-app green-build fixes, and the canonical image pipeline (Dockerfile +
hanzo.yml + cicd.yml). CI builds ghcr.io/hanzoai/cms from a repeatable trigger
for the first time.
2026-07-12 22:10:45 -07:00
hanzo-dev 8c1315dfbe build(cms): build-only pipeline + trigger on hanzo-cms mainline
hanzo.yml drops the deploy block (build-only first cutover — deploy via the
universe CR bump in lockstep with CMS_SECRET). cicd.yml triggers on hanzo-cms
(this repo's actual default branch) + main.
2026-07-12 22:10:44 -07:00
hanzo-dev 73c2a47eee build(cms): stand up the canonical image pipeline (Dockerfile + hanzo.yml + cicd.yml)
cms.hanzo.ai's image (cms:3.85.9) was built OUT-OF-BAND — no Dockerfile, no
hanzo.yml, zero GH Actions image runs ever. This commits the missing pipeline so
a rebranded image builds from a repeatable trigger instead of a dev box:

- apps/hanzo-demo/next.config.ts: output:'standalone' + outputFileTracingRoot at
  the workspace root, so the build emits .next/standalone/apps/hanzo-demo/server.js
  — exactly what the operator CR runs (node apps/hanzo-demo/server.js).
- Dockerfile: multi-stage, pnpm 10.27 (corepack), pnpm build:all + the app's
  next build --webpack, slim runner copying the standalone tree.
- hanzo.yml + .github/workflows/cicd.yml: the canonical hanzoai/ci path (mirrors
  hanzoai/world) — push to main builds ghcr.io/hanzoai/cms + rolls the cms CR;
  KMS supplies the GHCR token + kubeconfig. main.yml (upstream tests) untouched.

FIRST-CUT — needs a CI build to validate (a Payload monorepo standalone image is
finicky; I did NOT build it on the box per the CI/CD-only rule). If the existing
3.85.9 Dockerfile is available, it should supersede this.

Claude-Session: https://claude.ai/code/session_013jh8aka8q8RvhhVQ1psMeW
2026-07-12 22:08:04 -07:00
hanzo-dev 907b8a1e82 Merge fix/cms-demo-turbopack-root: green next build (webpack + turbopack.root) 2026-07-12 22:04:41 -07:00
hanzo-dev 557c4f854f fix(cms-demo): green next build in the pnpm workspace
The demo app failed "next build" for two independent, structural reasons
(neither caused by the Payload -> CMS rename):

1. Next 16 defaults to Turbopack, which refuses to resolve packages whose
   realpath lies outside turbopack.root. "next" is symlinked from the root
   .pnpm store, so with root = app dir it resolved outside the boundary ->
   "couldn't find the Next.js package (next/package.json)". Fixed by pointing
   turbopack.root at the monorepo root (two levels up).

2. In-workspace, every @hanzo/cms* package resolves to its raw TS src/ (via
   its exports map); those .js import specifiers map to .tsx files. webpack
   handles this via resolve.extensionAlias, but Turbopack ignores the webpack
   config -> 453 module-not-found errors. The whole monorepo builds on webpack
   (root next.config.mjs + the withCMS wrapper), so the app now builds and dev
   with "next build --webpack" / "next dev --webpack".

Also set typescript.ignoreBuildErrors (mirrors the monorepo root next.config):
resolving packages to src/ makes the app-level type-check re-check the entire
Payload source tree (OOMs / runs for many minutes) and it is redundant with
each package's own build:types (tsc --emitDeclarationOnly) run by turbo build.

Result: turbo build --filter @hanzo/cms-demo -> 14/14 tasks green.
2026-07-12 21:58:59 -07:00
hanzo-dev 1779549972 fix(cms): resolve type errors surfaced by the monorepo build (rename edge cases)
Real turbo build over the monorepo (pnpm 10.27) verified the Payload→CMS rename
compiles. 41/45 build tasks green — every @hanzo/cms* library package builds.
Fixed the edge cases the token-transform got wrong:

- auth/strategies/jwt.ts: transform renamed jose's { payload } destructure (EXTERNAL
  library property on JWTVerifyResult) to { cms } — reverted to { payload: decodedCMS }.
- auth/getAccessResults.ts: two stray payload.config where in-scope var is cms → cms.config.
- apps/hanzo-demo/next.config.ts + scripts/proof.ts (outside src/, missed by partition):
  withPayload→withCMS identifier (import path /withPayload kept), getPayload→getCMS,
  payload local-API object → cms, cms-tenant cookie log. payload.config.js path preserved.

core @hanzo/cms builds clean. Demo app's remaining failure is a Next Turbopack
workspace-root error (next/package.json resolution) — orthogonal to the rename.

Claude-Session: https://claude.ai/code/session_013jh8aka8q8RvhhVQ1psMeW
2026-07-12 21:26:20 -07:00
hanzo-dev 79fff23766 rename(cms): Payload → CMS across all 44 packages (identifiers, slugs, env, i18n, brand)
Complete de-brand of the fork the org owns (unpublished, empty DB — so no external
consumers and no data migration). 1308 files. Applied Payload→CMS / payload→cms /
PAYLOAD→CMS to: type/identifier names (PayloadRequest→CMSRequest, getPayload→getCMS,
BasePayload→BaseCMS, the request property req.payload→req.cms, PayloadComponent→
CMSComponent, usePayloadAPI→useCMSAPI, …); collection/DB slugs (payload-jobs→cms-jobs,
payload-kv, payload-migrations, payload-preferences, payload-locked-documents);
env vars (PAYLOAD_*→CMS_*); i18n key + values (payloadSettings→cmsSettings, 'Payload
Settings'→'CMS Settings' across 44 languages); CSS @layer/classes; comments/docs/UI.

PRESERVED (deliberate — renaming breaks resolution or law):
- MIT LICENSE + 'Copyright (c) 2018-2025 Payload CMS, Inc.' (legal attribution)
- every import/require/export specifier + path literal; on-disk filenames
  (payload.config.ts, payload-types.ts) + the packages/payload dir; @payload-config alias
- package.json "name" fields (already @hanzo/cms*)
- URLs (payloadcms.com); Redux action.payload (a different, unrelated field)

CONSISTENCY VERIFIED repo-wide: req.payload=0, from 'payload'=0, payloadSettings=0
(all now cms*), Redux action.payload intact, license intact. Individual files
transpile clean.

NOT YET VERIFIED: full type-compilation — requires a 44-package monorepo build
(node_modules absent). Green build is the gate before publish; not claimed here.

Claude-Session: https://claude.ai/code/session_013jh8aka8q8RvhhVQ1psMeW
2026-07-12 17:41:01 -07:00
hanzo-dev 0b9bbbec65 rebrand(cms): Hanzo branding on the public + admin surfaces
The deps are already forked in-tree (@hanzo/cms*, zero upstream @payloadcms,
zero bare 'payload' imports) — this strips the user-facing upstream BRAND that
still leaked on the surfaces cms.hanzo.ai actually serves:

- (frontend)/layout.tsx: title 'Payload Blank Template' → 'Hanzo CMS'.
- payload.config.ts admin.meta: title/titleSuffix/description → Hanzo CMS, so
  the admin panel Antje logs into no longer shows the upstream name.

MIT license + the upstream copyright line are retained (legal attribution
requirement of the MIT fork) — everything else rebrands to Hanzo.

Claude-Session: https://claude.ai/code/session_013jh8aka8q8RvhhVQ1psMeW
2026-07-12 16:29:26 -07:00