Skip to content

fix(dev): unify dev admin seed in-process; remove port-drift HTTP seed#1503

Merged
xuyushun441-sys merged 3 commits into
mainfrom
fix/dev-seed-admin-in-process
Jun 2, 2026
Merged

fix(dev): unify dev admin seed in-process; remove port-drift HTTP seed#1503
xuyushun441-sys merged 3 commits into
mainfrom
fix/dev-seed-admin-in-process

Conversation

@xuyushun441-sys

Copy link
Copy Markdown
Contributor

Problem

pnpm dev:showcase often failed to auto-seed a usable admin:

  • Port drift (the real bug): os dev seeded over HTTP against a hard-coded localhost:3000. In dev, serve auto-shifts off a busy port (3000 → 3001), but the parent never learned the new port and POSTed to 3000 — hitting the wrong server (or nothing). The showcase instance never got an admin.
  • Ghost admin: a second, divergent seed in plugin-dev inserted a raw sys_user row with no credential (admin@dev.local), producing an un-loginable account. It also wasn't even loaded by the showcase.

So we had two seeds: one in the right place (in-process) but broken (no credential, no promotion), and one correct (real auth path, promoted) but in the wrong place (HTTP, racing readiness, hard-coded port).

Fix — consolidate to one in-process seed

  • plugin-auth: maybeSeedDevAdmin() runs on kernel:ready. Creates admin@objectos.ai / admin123 through better-auth's real server-side signUpEmail pipeline (hashed credential + hooks) → fully loginable; plugin-security's first-user middleware promotes it to platform admin. Empty-DB only (excludes the SystemUserId.SYSTEM service account), idempotent, never overwrites an existing account. Hard-gated to NODE_ENV=development; opt out with OS_SEED_ADMIN=0. No port, no readiness race.
  • cli/dev: deleted the HTTP seedAdminAccount; --seed-admin now only passes OS_SEED_ADMIN[_EMAIL|_PASSWORD] to the serve child. Removed a dead port param from the watch loop.
  • cli/serve: publishes the actually-bound port — process.send({type:'objectstack:listening', port, url}) over IPC + a runtime.<env>.json state file under OS_HOME for external supervisors.
  • plugin-dev: removed the credential-less raw insert; seedAdminUser now maps to the unified OS_SEED_ADMIN toggle.

Verification (real showcase runs)

Behavior Result
Seed creates loginable admin sign-in admin@objectos.ai/admin123200
Platform-admin promotion sys_user_permission_setadmin_full_access, organization_id: null
Port auto-shift 3999 busy → bound 4000; parent logged the shift; seed landed on 4000 (old code seeded stale 3999)
runtime.json written {pid, port, url, environmentId, startedAt}
Opt-out (--no-seed-admin) child OS_SEED_ADMIN=0 → no seed → 401
Idempotent on persistent DB RUN2 same DB: sign-in 200, perm-set total 1 (no dup), sys_user count 2

Tests: plugin-auth 88, plugin-dev 7, cli 144 — all green. Typecheck/build clean.

🤖 Generated with Claude Code

os-zhuang and others added 2 commits June 2, 2026 08:52
feat(studio): AI-draft review/diff mode in the object designer (v1) (#1456)

objectui@fdd083657e2da9832059492d4c88e818a5990a8d
`pnpm dev:showcase` often failed to provision a usable admin. The CLI
seeded over HTTP against a hard-coded localhost:3000, but dev auto-shifts
off a busy port — so the POST hit the wrong server (or nothing) and the
showcase instance never got an admin. A second, divergent seed in
plugin-dev inserted a raw sys_user row with no credential, producing an
un-loginable ghost admin (admin@dev.local).

Consolidate to a single in-process seed in the runtime:

- plugin-auth: maybeSeedDevAdmin() runs on kernel:ready, creates the admin
  (admin@objectos.ai / admin123) through better-auth's real signUpEmail
  pipeline (hashed credential + hooks), so it is fully loginable;
  plugin-security's first-user middleware promotes it to platform admin.
  Empty-DB only (excludes the SystemUserId.SYSTEM account), idempotent,
  never overwrites an existing account. Hard-gated to NODE_ENV=development;
  opt out with OS_SEED_ADMIN=0. No port, no readiness race.

- cli/dev: delete the HTTP seedAdminAccount entirely; --seed-admin now just
  passes OS_SEED_ADMIN[_EMAIL|_PASSWORD] to the serve child. Drop the dead
  `port` param from the watch loop.

- cli/serve: publish the actually-bound port — process.send({type:
  'objectstack:listening', port, url}) over IPC + a runtime.<env>.json
  state file under OS_HOME for external supervisors.

- plugin-dev: remove the credential-less raw sys_user insert; seedAdminUser
  now maps to the unified OS_SEED_ADMIN toggle.

Verified on the showcase: loginable admin + platform-admin promotion,
correct seed under port auto-shift (3999 busy -> 4000), runtime.json
written, --no-seed-admin opt-out, and idempotency on a persistent DB (no
duplicate user / permission set). Tests: plugin-auth 88, plugin-dev 7,
cli 144 — all green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@vercel

vercel Bot commented Jun 2, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
spec Ready Ready Preview, Comment Jun 2, 2026 2:13am

Request Review

@github-actions github-actions Bot added the size/m label Jun 2, 2026
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actions github-actions Bot added documentation Improvements or additions to documentation tooling labels Jun 2, 2026
@xuyushun441-sys xuyushun441-sys merged commit 8c01eea into main Jun 2, 2026
12 checks passed
@xuyushun441-sys xuyushun441-sys deleted the fix/dev-seed-admin-in-process branch June 2, 2026 02:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/m tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants