Skip to content

feat: Wave 5 — follow-ups + CI main repair (6 commits)#531

Open
tayebmokni wants to merge 6 commits into
feat/wave-4-refactorfrom
feat/wave-5-followups
Open

feat: Wave 5 — follow-ups + CI main repair (6 commits)#531
tayebmokni wants to merge 6 commits into
feat/wave-4-refactorfrom
feat/wave-5-followups

Conversation

@tayebmokni
Copy link
Copy Markdown
Contributor

Stacked on PR #530PR #529PR #528PR #527PR #523.

Wave 5: follow-ups from earlier PRs + pre-existing main-CI repair.

6 commits

  1. feat(db): add plugins table migration (000040) — unblocks the lifecycle Storage CRUD that PR feat: Wave 3 — 4 large features (plugins CRUD, PAT, customizer preview, Pages real) #529 mounted
  2. fix(api): honor body `post_type` on POST /api/v1/posts — admin /pages/new actually creates pages now (gap flagged in PR feat: Wave 3 — 4 large features (plugins CRUD, PAT, customizer preview, Pages real) #529's Admin Pages module is non-functional — SEED_PAGES list, console.log save, disabled editor #506)
  3. chore(api): delete unused `apps/api/internal/admin/tokens` package — PAT consolidation flagged in PR feat: Wave 3 — 4 large features (plugins CRUD, PAT, customizer preview, Pages real) #529's Mount /api/v1/tokens — Personal Access Token issuance #511
  4. test: fix pre-existing test-go failures — config.LoadMinimal for CLI subcommands, drop t.Parallel from globals-mutating tests, renumber 6 duplicate migrations
  5. refactor(admin): migrate 7 more api-types consumers (Generate @gonext/api-types from existing OpenAPI spec — eliminate per-page envelope adapters #514 follow-up after PR feat: Wave 4 — api-types from OpenAPI + regression test backfill #530's pilot)
  6. chore(ci): fix docs artifact upload (include-hidden-files) + bump Go to 1.25.10 + x/net to v0.55.0 (clears all govulncheck findings)

What this unblocks

  • All 6 pre-existing main-CI failures (build / security-scan / 2× test-go / smoke / e2e) should now be addressed:
    • build: docs Next.js artifact actually uploaded
    • security-scan: govulncheck "No vulnerabilities found" across all modules
    • test-go (1): audit + jobs tests pass with LoadMinimal + sequential goroutine handling
    • test-go (2): migrate test passes after duplicate-version renumbering
    • smoke/e2e: cascade-fixed (depended on build)
  • The plugins lifecycle endpoints PR feat: Wave 3 — 4 large features (plugins CRUD, PAT, customizer preview, Pages real) #529 mounted now work end-to-end (table exists)
  • Admin /pages/new persists as actual pages

Verification

  • `go vet ./...` clean (7 workspace modules)
  • `go test -short -race ./...` clean across api / worker / cli / packages
  • `govulncheck ./...` — "No vulnerabilities found." on every module
  • `pnpm exec tsc --noEmit` 0 errors
  • `pnpm test --run` admin 657/657 pass (unchanged count, 7 type-only migrations preserved behavior)

Known follow-ups surfaced

  • `packages/go/auth/pat` is now orphan (the only importer was the deleted admin/tokens). Cleanup pending.
  • Admin TS `IssuedTokenView` expects `plaintext` + `effective_scopes`; the kept Go handler emits `token` only. TokenReveal flow shape mismatch — small follow-up.
  • Several wire types still hand-typed because the OpenAPI spec doesn't model them yet: media, users, redirects, performance, status, comment-row extras. Spec extension is a follow-up.

🤖 Generated with Claude Code

tib0o0o and others added 6 commits May 28, 2026 13:40
PR #529 mounted /api/v1/plugins on top of lifecycle.PostgresStorage,
but the \`plugins\` table had no migration. PR #527 made List handle
SQLSTATE 42P01 gracefully (returns empty), so the list endpoint
didn't 500 — but Get/Install/UpdateState/Delete would. Any actual
plugin install attempt against a fresh DB explodes.

Schema matches what packages/go/plugins/lifecycle/postgres.go
actually reads and writes (verified against insertSQL + selectColumns):

    plugins(
      slug CITEXT PRIMARY KEY,         -- not "name"
      version TEXT NOT NULL,
      abi_version TEXT NOT NULL,
      manifest JSONB NOT NULL,
      state TEXT NOT NULL CHECK (state IN
        ('installed','active','inactive','pending_uninstall','errored')),
      capabilities JSONB NOT NULL DEFAULT '[]',
      last_error TEXT,
      error_at TIMESTAMPTZ,
      installed_at TIMESTAMPTZ NOT NULL DEFAULT now(),
      activated_at TIMESTAMPTZ,
      row_version BIGINT NOT NULL DEFAULT 1,
      updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
    )

The state CHECK values come from state.go's State enum (NOT the
\`installing\`/\`uninstalling\` the task brief speculated). Trigger
reuses the shared \`touch_updated_at()\` helper from 000004_posts.

Index plugins_state_idx ON (state) for the hot-path filter.

Down migration drops trigger + index + table cleanly.

Verified: after applying, previously-500 endpoints return proper
404s (no row). Storage tests pass against the live schema.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: Tayeb Mokni <tayeb.mokni@gmail.com>
…ate)

PR #529's commit \`feat(admin+api): wire admin Pages module to real
API (#506)\` added a body-level \`post_type\` field on the admin
/pages/new flow but the create handler was hard-coded to the mount's
PostType — so new pages inserted as post_type='post' rows and
disappeared from the pages list.

Fix:
- CreateInput grows \`PostType *string \`json:\"post_type,omitempty\"\`\`
- create() resolves the type: body override wins when non-nil and
  non-empty, otherwise the mount default
- Closed-set validation: {post, page} only; everything else → 400
  invalid_post_type

The notifyRevalidate + emitAudit helpers still read h.postType
(the mount default) — out of scope here. If a publish-on-create
with a body-overridden type ever needs ISR routing or audit-type
aligned with the actual stored row, that's a follow-up. Doesn't
affect admin /pages/new today (always creates drafts).

4 new tests: default-uses-mount-PostType, body override to page,
invalid post_type rejected, pages-mount body-omitted still pages.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: Tayeb Mokni <tayeb.mokni@gmail.com>
PR #529's commit \`feat(auth): mount /api/v1/me/tokens — Personal
Access Tokens (#511)\` flagged the older admin/tokens package as
\"currently unmounted; pick one + repoint\". Investigation:

- main.go never imported apps/api/internal/admin/tokens
- No /api/v1/admin/users/{id}/tokens route was wired anywhere
- Admin frontend (settings/tokens) consumed only /api/v1/me/tokens
  via the new auth/pat package

So the old package was completely orphan code. Delete it.

- Removed: apps/api/internal/admin/tokens/{doc.go, handler.go,
  handler_test.go}
- Fixed stale comment in apps/admin/src/app/(authenticated)/
  settings/tokens/types.ts pointing at the deleted file

Out-of-scope follow-ups flagged separately:
1. packages/go/auth/pat (the lower-level credential primitive) is
   now orphan too — its only importer was this deleted package.
   Cleanup pending.
2. Admin TS IssuedTokenView expects \`plaintext\` + \`effective_scopes\`
   fields; the kept Go handler emits \`token\` (no scopes intersection).
   TokenReveal flow needs a JSON-shape fix.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: Tayeb Mokni <tayeb.mokni@gmail.com>
Three distinct root causes — not the single env-var thread the
follow-up issue speculated:

### 1. cli/gonext/cmd/audit.TestVerify_MissingKey

config.Load() now requires GONEXT_AUTH_PEPPER, _SESSION_SECRET,
_CSRF_SECRET. The test only sets GONEXT_AUDIT_HMAC_KEY; it got
\"required env var GONEXT_AUTH_PEPPER missing\" instead of the
HMAC key error the test expects.

Root cause: CLI subcommands shouldn't use the full production
config loader. \`audit verify\` doesn't touch auth.

Fix (option (a)): new \`packages/go/config/LoadMinimal()\` that
loads only Env/Database/Redis. audit/verify.go switched to call
LoadMinimal instead of Load.

Production binaries (apps/api, apps/worker) keep using Load —
auth secret validation untouched there.

### 2. cli/gonext/cmd/jobs (5 tests)

Tests call t.Parallel() while mutating package-level
\`inspectorFactory\` / \`cronRegistryFactory\` globals through
\`withStub\`. Race detector flags concurrent reads/writes →
cascade fail under -race.

Removed t.Parallel() from the 5 tests that swap globals.
Kept on TestPluginPrefix (pure-function only).

### 3. packages/go/migrate.TestRun_IntegrationApplyAndRollback

migrations/ has duplicate version numbers — three 000033_*,
four 000035_*, two 000036_*. golang-migrate refuses to load
with \"duplicate migration file\".

Renumbered 6 duplicate files to unique slots 41–46 (kept the
earliest-merged variant at each duplicate slot). Updated the
\`-- 0000NN_...\` header comments inside each SQL file. Pattern
matches PR #486 which previously did similar renumbering.

### 4. packages/go/plugins/debug.TestLogStreamHandler_RoundTrip

Reported as failing but actually passes on CI with
\"coverage: 75.1% of statements\". False positive — no fix needed.

### Verification

- \`cd cli/gonext && go test -race -count=1 ./...\` — all packages pass
- \`cd packages/go && DATABASE_URL=... go test -count=1 ./...\` —
  80+ packages pass
- Ran jobs/audit suites 5× each — no flakes

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: Tayeb Mokni <tayeb.mokni@gmail.com>
…follow-up)

PR #530 set up the api-types package + pilot. Continue the migration
with 7 type-only consumer swaps. All baseline tests still pass.

Migrated:
1. posts/columns.tsx — Post['status'] (PostStatus enum)
2. posts/[id]/page.tsx — Post['status'] + PostUpdate (BlockTree
   override for content_blocks)
3. comments/types.ts — Comment['status'] (CommentStatus enum)
4. webhooks/types.ts — Webhook (Pick projection), WebhookCreate,
   WebhookUpdate
5. pages/page.tsx — Page['status'] + Partial<Page>
6. posts/new/page.tsx — Post['status'], PostCreate (tightened
   title/slug/status), Pick<Post,'id'> for response
7. jobs/dlq/types.ts — ArchivedTask (tightened failed_at to
   required), RedactRequest extended with queue

Pattern matches the pilot:
- Status enums via \`components['schemas']['X']['status']\` so spec
  changes are type errors at the call site
- \`Omit<… , 'f'> & { f: tighter-type }\` where UI needs narrower
  than spec
- \`Partial<components['schemas']['X']>\` for sparse list projections

Skipped (tracked separately — spec schemas missing or shape too
divergent for type-only migration):
- media/types.ts (admin shape uses alt_text/filename/storage_key;
  spec uses alt/mime/url)
- users/types.ts (admin singular \`role\` + handle; spec roles array
  + slug)
- redirects/types.ts (no spec schema)
- comments WireComment row shapes (admin endpoint has extras the
  spec doesn't model)
- performance/types.ts (uppercase enum vs lowercase)
- status/types.ts (typed nested cards vs generic shape)
- packages/ts/sdk (no src/types.ts)

Total diff: +151 / -62 across 7 files. 657/657 admin tests pass.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: Tayeb Mokni <tayeb.mokni@gmail.com>
…ecurity-scan

Two pre-existing CI failures on main:

### 1. \`build\` job: \"No files at apps/docs/.next\"

Not a build failure — Next.js DID write \`.next/\`. \`actions/upload-
artifact@v4\` defaults \`include-hidden-files: false\`, and \`.next\`
is a dot-prefixed (hidden) directory. The action's filter silently
skipped the whole artifact even though the build succeeded.

Fix: \`.github/workflows/docs.yml\` upload step gets
\`include-hidden-files: true\`.

### 2. \`security-scan\` govulncheck stdlib + x/net CVEs

setup-go was installing Go 1.25.7 (workspace pin is \`go 1.25.0\`
with no toolchain directive — Actions picked the latest 1.25.x at
runtime, which had 13 stdlib CVEs).

govulncheck found vulnerabilities in:
- 8 stdlib functions (net/mail.ParseAddress, html/template.Execute,
  net.Listen, crypto/tls, crypto/x509, net/http, os, net/url)
  → patched at go1.25.10
- 5 golang.org/x/net/html functions (html.Parse, html.ParseFragment)
  → patched in golang.org/x/net v0.55.0 — separate from the Go
  toolchain bump

Fixes:
- go.work: added \`toolchain go1.25.10\` directive.
- 3 Dockerfiles (apps/api, apps/worker, cli/gonext): bumped
  \`FROM golang:1.25-alpine\` → \`golang:1.25.10-alpine\` (pinned).
- packages/go/go.mod: \`golang.org/x/net v0.54.0\` → \`v0.55.0\`.
- Tidies for apps/api, apps/worker, cli/gonext propagated the bump.

### Verification

- go vet ./... clean across all 7 workspace modules
- go test -short -count=1 ./... clean
- govulncheck ./... — \"No vulnerabilities found.\" on every module
- pnpm --filter @gonext/docs build still produces .next/ with 61
  static pages

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: Tayeb Mokni <tayeb.mokni@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants