feat: native REST + DataLoader + comment hooks + strict input + custom fields + audit/jobs CLIs#492
Merged
Merged
Conversation
|
Heads up — this PR touches strings that often signal a security disclosure ( If this PR fixes or describes a real vulnerability that has not yet been publicly disclosed, please stop and use the private path:
See If this is a false positive (test fixture, doc update, release notes, etc.) please ignore this comment — the check is advisory only and does not block the PR. Matched files:
|
Adds public read-only REST surfaces mirroring the posts contract:
GET /api/v1/users[/{id|handle}]
GET /api/v1/media[/{id}] ?mime_class=image|video|document
GET /api/v1/terms[/{id}] ?taxonomy=&parent_id=&search=
GET /api/v1/taxonomies[/{slug}]
GET /api/v1/comments[/{id}] ?post_id=
The users surface omits PII (email, password material, capabilities);
media omits uploader id + SHA256; terms surfaces ltree path + depth
for breadcrumb rendering without follow-up queries. Comments adds a
global read endpoint alongside the existing per-post submit/list.
All four packages share the cursor-based pagination shape from
router.Page[T] and the RFC-7807 error envelope from router.WriteError.
In-memory Store implementations back the unit tests; Pg-backed stores
will swap in via the same interfaces.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: Tayeb Mokni <tayeb.mokni@gmail.com>
Extends apps/api/internal/graphql/dataloader with per-request batchers for User, Term, Media, and TermsByPostID — each one a candidate N+1 dimension. Loaders embed atomic counters so a benchmark can read back the per-resolver batch-round-trip count for budget enforcement. Adds tools/graphql-budgets.yml as the single source of truth for per-operation batch ceilings, plus a CI workflow that runs the BenchmarkGraphQLBudgets harness on PRs that touch the GraphQL surface or the budget file. The bench drives each operation with a representative fan-out and fails the run if dataloader.Snapshot() exceeds the configured budget. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> Signed-off-by: Tayeb Mokni <tayeb.mokni@gmail.com>
) Three layered moderation primitives wired into the public submit path: - pre_submit filter hook ("rest.comments.pre_submit") that plugins register through hooks.Bus. Handlers may (a) mutate the input, (b) hard-reject with ErrCommentRejected (→ 422), or (c) stamp a CommentVerdict that overrides the default classifier. - Duplicate-content gate: SHA-256 of normalised content + IP within a 5-minute window drops the second submission at 422. Anonymous only — logged-in users opt out. - IP redaction cron: RedactIPsBefore zeroes the last octet (IPv4) or last 80 bits (IPv6) of every comment row older than 30 days, preserving the /24 or /48 prefix for abuse-pattern triage. The HookBus dependency is an interface, not a hard import, so the package stays decoupled from packages/go/hooks. DupChecker is similarly optional. MemoryStore implements both for tests + the no-DB fall-through. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> Signed-off-by: Tayeb Mokni <tayeb.mokni@gmail.com>
Adds packages/go/middleware/strictinput — opt-in middleware engaged by
GONEXT_STRICT_INPUT=1 that enforces request-shape budgets in front of
the REST + GraphQL surfaces.
REST: JSON bodies under /api/v1/* must parse as a single JSON value
with no trailing data. The unknown-fields rejection stays at the
per-handler level (where the route's payload struct is the authority).
GraphQL: bodies must conform to the {query,variables,operationName,
extensions} envelope; any other top-level key is a 400. Variables and
extensions are bounded by depth (default 8) and recursive key count
(default 100) so a hostile client cannot bury query-cost under a
deeply nested variable tree.
Disabled by default so the gate can land incrementally; flipping the
env var on once a deployment has audited its surface is a one-line
change.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: Tayeb Mokni <tayeb.mokni@gmail.com>
New packages/go/customfields owns the runtime + storage primitives for
custom fields (GoNext's equivalent of ACF):
- FieldGroup carries a draft 2020-12 JSON Schema describing what a
group's meta blob may contain.
- Validate applies the schema to a candidate blob, returning every
violation in one multi-error so the admin can fix N issues at
once.
- MetaStore interface persists (post_id, group_id) -> validated
blob. MemoryStore backs tests; the new field_groups +
post_meta_values tables back production (migration 000035).
apps/api/internal/rest/customfields wires the CRUD surface:
/api/v1/custom-fields/groups (list, create, get, patch, delete)
/api/v1/posts/{id}/meta[/{group}] (list, get, put — schema-validated)
PUT meta paths validate against the resolved group's schema before
persistence; schema violations return 422 with the multi-error.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: Tayeb Mokni <tayeb.mokni@gmail.com>
gonext audit tail (#223): Pulls recent events from the audit store; --follow polls every 1s using the last observed event's timestamp as the cursor. --json emits one event per line for jq pipelines; default is tab-delimited. Default limit is 50 events; --limit caps at 1000. Filters cover --type, --actor, --plugin, --severity, --since. gonext jobs (#273): - queue: list configured queues + size/active/pending/scheduled/ retry/archived counts via asynq.Inspector. - failed: list archived (DLQ) tasks per queue with last error. - drain: delete every archived task (with confirmation; --yes skips the prompt). - cron: print the registered cron schedules from the boot snapshot. - plugin: aggregate per-plugin task counts by scanning archived task types' "{plugin}." prefix. Inspector is an interface so each subcommand can be unit-tested without a live Redis. Audit's tail likewise takes an injected store factory for the same reason. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> Signed-off-by: Tayeb Mokni <tayeb.mokni@gmail.com>
2d9a3d8 to
9ebce7f
Compare
This was referenced May 26, 2026
This was referenced May 26, 2026
tayebmokni
pushed a commit
that referenced
this pull request
May 28, 2026
cli/gonext/cmd/audit/audit.go and verify.go both declared the same package-level symbols — ExitOK, ExitFail, ExitUsage, usage, Run, RunOS — because the verify.go landed in PR #492 carrying its own copy of the entry-point boilerplate that was already in audit.go. \`go vet\` rejects this with \"X redeclared in this block\" and CI lint-go has been red on main since the merge. Make audit.go the single owner of the package surface: - Add \`case \"verify\": return runVerify(args[1:], stdout, stderr)\` to the dispatch switch. - Extend the usage banner with the verify subcommand and its env requirement (GONEXT_AUDIT_HMAC_KEY). Strip verify.go down to just \`runVerify\` and its imports — everything else (exit codes, Run, RunOS, usage) is owned by audit.go. go vet ./... clean on cli/gonext after this change. cli/gonext/cmd/ audit unit tests still pass. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> Signed-off-by: Tayeb Mokni <tayeb.mokni@gmail.com>
11 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #78, #115, #152, #161, #162, #223, #273.