Skip to content

fix(json): emit canonical camelCase JSON wire keys#196

Open
hortison wants to merge 1 commit into
masterfrom
fix/canonical-camelcase-curriculum-json
Open

fix(json): emit canonical camelCase JSON wire keys#196
hortison wants to merge 1 commit into
masterfrom
fix/canonical-camelcase-curriculum-json

Conversation

@hortison
Copy link
Copy Markdown
Contributor

Summary

Flips the remaining snake_case JSON output keys to camelCase across three theme templates, completing the canonical wire-tag contract for the academy JSON view files that meshery-cloud reads at runtime via LoadCurricula.

The hard prerequisite

layouts/partials/learning-path.json.html line 23 emits "org_id", which populates AcademyCurricula.OrgId in the cloud-side decode. The academy schema flipped this wire tag between v1beta2 (json:"org_id") and v1beta3 (json:"orgId"), and v1beta3 has no UnmarshalJSON fallback (confirmed against models/v1beta3/academy/zz_generated.helpers.go). Without this change, the planned meshery-cloud v1beta3 migration (layer5io/meshery-cloud#5379) would have every LoadCurricula silently write nil-OrgId rows and break org-scoped curriculum lookups.

Adjacent canonical-casing alignment (same PR)

Folded in per the maintainer-mindset rule (pay down adjacent debt while in the area). Every JSON output key the theme emits is now canonical camelCase:

File Snake -> camel
layouts/partials/learning-path.json.html org_id, total_courses, total_tests, total_modules, total_pages, prerequisite_knowledge, related_resources, additional_attributes
layouts/partials/common-curricula-properties.html reading_time, prerequisite_knowledge, related_resources
layouts/lab/single.json.json starter_catalog_link, starter_embed_link, answer_catalog_link, answer_embed_link

The quiz template (layouts/partials/test/single.html) was already camelCase; this PR brings the remaining three to parity. The build (layer5io/academy-build) must be re-run after merge to publish refreshed index.json artifacts before any cloud v1beta3 deploy.

What does NOT change

  • Source-side reads (.Params.<snake_case>) are left untouched. They match existing frontmatter keys in the content repos (layer5io/layer5-academy, layer5io/exoscale-academy, meshery-extensions/meshery-academy, layer5io/academy-example). The transformation is purely on the JSON output side, so no content repo requires any change for this migration.
  • Hugo template logic, variable expressions, or any structural code. The diff is +15/-15, exclusively the string literals inside the JSON object keys.

Test plan

This is a pure string-literal change to JSON-emitting Hugo templates. Hugo template parsing is unaffected by string content. Verification:

  • grep -rnE '"[a-z]+_[a-z_]+":' layouts/ --include='*.html' --include='*.json' returns empty post-edit (zero residual snake_case JSON output keys across the theme). Confirmed locally.
  • Reviewer to confirm via a Hugo build against a content site (e.g. layer5-academy or academy-example), then inspect public/learning-paths/index.json for orgId (camelCase) and absence of org_id. Local Hugo build was attempted but the docsy transitive module resolution conflicted with the local-replacements env var setup; the change is mechanical enough that a CI-driven build verification is the appropriate gate.
  • Downstream verification: meshery-cloud's planned v1beta3 academy PR (Phase 1 of meshery-cloud#5379) confirms LoadCurricula writes non-nil OrgId rows.

Related

  • meshery-cloud#5379 — the migration plan that requires this Phase 0.
  • meshery/schemas v1beta3 academy (models/v1beta3/academy/) — the canonical-casing schema, released since v1.2.12.
  • layer5io/academy-build — needs a re-run after this PR merges, before any v1beta3 cloud deploy.

Flips snake_case JSON output keys to camelCase across the three remaining
templates that still emit snake form, completing the canonical wire-tag
contract for the academy JSON view files.

Hard prerequisite for the meshery-cloud v1beta3 academy migration:
- learning-path.json.html line 23 emits 'org_id', which populates
  AcademyCurricula.OrgId. v1beta2 had json:'org_id', v1beta3 (released in
  schemas v1.2.12) has json:'orgId' and no UnmarshalJSON fallback. Without
  this change, cloud reading curriculum on v1beta3 would silently write
  nil-OrgId rows and break org-scoped curriculum lookups.

Adjacent canonical-casing alignment (same theme PR, consistent wire form):
- learning-path.json.html: total_courses/total_tests/total_modules/
  total_pages -> totalCourses/totalTests/totalModules/totalPages;
  prerequisite_knowledge/related_resources/additional_attributes ->
  prerequisiteKnowledge/relatedResources/additionalAttributes.
- common-curricula-properties.html: reading_time/prerequisite_knowledge/
  related_resources -> readingTime/prerequisiteKnowledge/relatedResources.
- lab/single.json.json: starter_catalog_link/starter_embed_link/
  answer_catalog_link/answer_embed_link -> starterCatalogLink/
  starterEmbedLink/answerCatalogLink/answerEmbedLink.

The Hugo source-side reads (.Params.<snake_case>) are left unchanged: they
match the existing frontmatter keys in the content repos (layer5-academy,
exoscale-academy, meshery-academy, academy-example), so no content-repo
change is required. The transformation is purely on the JSON output side.

Theme partials test/single.html (quiz) was already camelCase; this PR
brings the remaining three to parity. Post-merge, every JSON wire key the
theme emits is canonical camelCase (verified: grep for snake-cased JSON
keys across layouts/ returns empty).

Signed-off-by: Alex Quinn <227241865+alexquincy@users.noreply.github.com>
@github-actions
Copy link
Copy Markdown

🚀 Preview deployment: https://layer5io.github.io/academy-theme/pr-preview/pr-196/

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR standardizes the JSON “wire” keys emitted by the academy theme’s JSON templates by converting remaining snake_case output keys to canonical camelCase, aligning with the v1beta3 academy schema expectations used by meshery-cloud’s LoadCurricula.

Changes:

  • Updated learning-path.json.html to emit orgId and camelCase aggregate/metadata keys (e.g., totalCourses, prerequisiteKnowledge).
  • Updated common-curricula-properties.html to emit camelCase keys (e.g., readingTime, relatedResources).
  • Updated the lab JSON output (single.json.json) to emit camelCase link keys (e.g., starterCatalogLink, answerEmbedLink).

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
layouts/partials/learning-path.json.html Converts learning-path JSON output keys (including orgId) from snake_case to camelCase.
layouts/partials/common-curricula-properties.html Converts shared curricula JSON property keys (e.g., reading time and resource fields) to camelCase.
layouts/lab/single.json.json Converts lab JSON output link field keys to camelCase.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates several Hugo template files, including layouts/lab/single.json.json, layouts/partials/common-curricula-properties.html, and layouts/partials/learning-path.json.html, to convert JSON output keys from snake_case to camelCase. Specifically, keys such as starter_catalog_link, reading_time, org_id, and various total_ count fields have been renamed to their camelCase equivalents. I have no feedback to provide.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants