feat(platform): structured platform registry + /api/v1/platforms; update server reads registry [#367] #826
Reference in New Issue
Block a user
Delete Branch "feature/platform-registry"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Turns the flat admin
[metadata] PLATFORM_OPTIONSkey list into a structured platform registry where each platform key carries capability attributes, and exposes it so CI / the update server / mokocli can read platform behavior from config instead of hardcoding it.Not built/deployed — requires forge rebuild + redeploy; review signatures. Companion to the CI/mokocli rewiring (separate).
Storage choice
New
[metadata] PLATFORM_REGISTRYkey inapp.ini: either an inline JSON array of platform objects, or a path to a JSON file (e.g.custom/platforms.json, relative paths resolved againstCustomPath). Parsed inmodules/setting. No DB table — idiomatic (mirrors existingapp.ini+ file-path config patterns), and the registry is non-secret capability config only (never credentials/tokens/keys). A built-in DEFAULT registry (joomla, dolibarr, go, npm, mcp, generic) keeps behavior unchanged when unconfigured, and reconciles with the existingPLATFORM_OPTIONSkey list.Schema (
PlatformDef)key, label, aliases, family, artifact(bool), update_generator, feed_format, template_repo, manifest_based(bool), publish_target, detect_globs. Everything defaults offfamily=generic.New endpoints
GET /api/v1/platforms— whole registry (list of capability objects). This is what CI/mokocli read.GET /api/v1/platforms/{key}— one platform (404 if not registered).Wired into the public-accessible misc API group (same visibility as
/settings,/licenses).Update server rewiring (minimal / additive)
Added
services/updateserver/registry.gowithGeneratorForPlatform,FeedFormatForPlatform,ContentTypeForPlatform,PlatformServesGenerator— registry lookups that replace the hardcoded per-platform generator/feed decisions. Handler bodies inrouters/web/repo/updateserver.gowere left untouched to avoid conflicting with PR #825.Overlap with PR #825 (
feature/updateserver-npm-mcp, open, not merged)PR #825 concurrently modifies
routers/web/repo/updateserver.goand addsmodels/updateserver/platform.go(platform constants +ResolvePlatform+IsFeedlessPlatform). To stay compatible and avoid a heavy conflict, this PR is deliberately additive and does not edit those files' handler bodies. The helpers here are drop-in replacements for the per-platform gating and can be adopted once #825 lands (e.g.if !PlatformServesGenerator(platform, "joomla")). No file conflicts expected: this PR only addsservices/updateserver/registry.goin that package.Admin UI
Read-only resolved-registry table added to Admin -> Metadata; the textarea still edits the flat key list. Capability attributes are edited via
app.ini [metadata] PLATFORM_REGISTRYfor now (structured editor deferred as too invasive).Scope guard
Does not touch
models/repo/repo_manifest.goor the per-repoapiMetadatastruct (owned by a separate PR). Registry is a separate endpoint, not embedded in/metadata.Build/format status
No Go toolchain in this environment — unbuilt,
go vetnot run, not gofmt'd by tool. Files written to gofmt conventions; signatures matched against existing handlers (ctx.PathParam,ctx.APIErrorNotFound,ctx.JSON;mischandler pattern; swagger response wrappers).Files
modules/setting/platform_registry.go(new) —PlatformDef, registry, default registry, loadermodules/setting/metadata.go— callloadPlatformRegistryFrommodules/structs/miscellaneous.go—PlatformAPI structrouters/api/v1/misc/platforms.go(new) —ListPlatforms/GetPlatformrouters/api/v1/swagger/misc.go—Platform/PlatformListresponsesrouters/api/v1/api.go— routesrouters/web/admin/metadata.go+templates/admin/metadata.tmpl— read-only registry tableservices/updateserver/registry.go(new) — registry-driven dispatch helperscustom/conf/app.example.ini— documented[metadata]sectionhttps://claude.ai/code/session_015UauDPfYC8S2mdUhoSK8zQ
Turn the flat admin [metadata] PLATFORM_OPTIONS key list into a structured platform registry where each key carries capability attributes (family, artifact, update_generator, feed_format, template_repo, manifest_based, publish_target, detect_globs, aliases), and expose it so CI / the update server / mokocli can read platform behavior from config instead of hardcoding. Storage: new [metadata] PLATFORM_REGISTRY key in app.ini — inline JSON array or a path to a JSON file (e.g. custom/platforms.json), parsed in modules/setting. No DB table (idiomatic: mirrors existing app.ini + file-path config patterns; non-secret capability config only). Built-in DEFAULT registry (joomla, dolibarr, go, npm, mcp, generic) keeps behavior unchanged when unconfigured, and reconciles with PLATFORM_OPTIONS. API: GET /api/v1/platforms (whole registry) and GET /api/v1/platforms/{key} (one), wired into the public misc group. Update server: additive registry-driven helpers in services/updateserver (GeneratorForPlatform / FeedFormatForPlatform / ContentTypeForPlatform / PlatformServesGenerator) that replace hardcoded per-platform generator/feed decisions with registry lookups. Handler bodies left untouched to avoid conflicting with PR #825 (feature/updateserver-npm-mcp), which is concurrently rewiring routers/web/repo/updateserver.go and adding models/updateserver/platform.go; helpers are drop-in for adoption once #825 lands. Admin UI: read-only resolved-registry table added to Admin -> Metadata; the textarea still edits the flat key list. Capabilities edited via config for now. Does NOT touch models/repo/repo_manifest.go or the per-repo apiMetadata struct (owned by a separate PR). Authored-by: Moko Consulting