@prefix this: . @prefix sub: . @prefix np: . @prefix grlc: . @prefix dct: . @prefix nt: . @prefix npx: . @prefix xsd: . @prefix rdfs: . @prefix orcid: . @prefix prov: . @prefix foaf: . sub:Head { this: a np:Nanopublication; np:hasAssertion sub:assertion; np:hasProvenance sub:provenance; np:hasPublicationInfo sub:pubinfo . } sub:assertion { sub:get-view-version-history a grlc:grlc-query; dct:description "Returns the version history of a space-governed resource view given as the resource (its version-independent IRI), for display on its maintained-resource page; the view counterpart of get-template-kind-version-history. Each row is a nanopub whose embedded resource view declares dct:isVersionOf the given view -- including superseded and retracted versions, which are marked 'superseded' or 'retracted' (only invalidations signed with the version's own key count, as in nanopub-level invalidation) -- showing its creation date, the version's title (falling back to its label), the change note attached to that version's publication info (skos:changeNote, truncated to its first line and at most 50 characters), and its author (signer, with the name resolved from the spaces trust state where available; the agent-to-name map is materialized once in a self-contained sub-select and matched by string containment, so the number of federated calls does not grow with the number of versions). The row marked '✓ current' is the current governed winner of the (view, space) pair -- the newest non-invalidated version signed by a current member+ of the governing space, with the view validated as maintained by that space (mirroring the get-latest-governed-version resolver); the winner is computed for the given view only, in a sub-select with its own values block, and matched by string containment. The restore_target column carries the nanopub URI for every row that is neither the current winner nor retracted (empty otherwise), and the restore_template column carries the template that version was created from (its nt:wasCreatedFromTemplate, lexicographically first where there are several, or the generic view template where that link is absent), so a per-row action can offer to restore an older version: overriding it republishes its content as the newest version, which is the cross-key way to undo a change. Publishing a new version from the current one is offered in the view-info panel instead. Rows are ordered newest first."; dct:license ; rdfs:label "Get view version history"; grlc:endpoint ; grlc:sparql """prefix rdfs: prefix dct: prefix np: prefix npa: prefix npx: prefix gen: prefix foaf: prefix nt: prefix skos: select ?Date ?Title ?Change_note ?Author ?Author_label ?Status_noheader ?restore_target ?restore_template ?np ?np_label where { values ?_resource_multi_iri {} { select (group_concat(?w1; separator=\"|\") as ?winners) where { { select ?gKind ?gSpace (max(concat(str(?gDate), \">\", str(?gNp))) as ?maxW) where { values ?_resource_multi_iri {} graph ?gA { ?gVersion dct:isVersionOf ?_resource_multi_iri ; gen:governedBy ?gSpace . } bind(?_resource_multi_iri as ?gKind) graph npa:graph { ?gNp npa:hasValidSignatureForPublicKeyHash ?gPubkeyhash ; dct:created ?gDate ; npx:embeds ?gVersion ; np:hasAssertion ?gA . filter not exists { ?gInv npx:invalidates ?gNp ; npa:hasValidSignatureForPublicKeyHash ?gPubkeyhash . } } service { graph npa:graph { npa:hasCurrentSpaceState ?stateG . } graph ?stateG { ?gKind npa:isMaintainedBy ?gSpace ; npa:hasGoverningSpaceRef ?gRef . ?gRi a gen:RoleInstantiation ; npa:forSpace ?gSpace ; npa:forSpaceRef ?gRef ; npa:hasRoleType ?gTier ; npa:forAgent ?gAgent . values ?gTier { gen:AdminRole gen:MaintainerRole gen:MemberRole } ?gAcct a npa:AccountState ; npa:agent ?gAgent ; npa:pubkey ?gPubkeyhash . } } } group by ?gKind ?gSpace } bind(concat(str(?gKind), \">\", str(?gSpace), \">\", ?maxW) as ?w1) } } { select (group_concat(?nEntry; separator=\"|\") as ?names) where { { select ?nAgent (min(?nNameRaw) as ?nName) where { service { graph npa:graph { npa:hasCurrentSpaceState ?nStateG . } graph ?nStateG { ?nAgent foaf:name ?nNameRaw . } } } group by ?nAgent } bind(concat(str(?nAgent), \">\", ?nName) as ?nEntry) } } graph ?a { ?version a gen:ResourceView ; dct:isVersionOf ?_resource_multi_iri . } graph npa:graph { ?np npa:hasValidSignatureForPublicKeyHash ?pubkeyhash ; npx:embeds ?version ; dct:created ?Date ; np:hasAssertion ?a ; np:hasPublicationInfo ?pi . } optional { graph npa:graph { ?np npx:signedBy ?Author . } } optional { graph ?a { ?version dct:title ?titleVal } } optional { graph ?a { ?version rdfs:label ?labelVal } } optional { graph ?a { ?version gen:governedBy ?space } } optional { graph ?pi { ?np skos:changeNote ?noteRaw } } optional { graph ?pi { ?np nt:wasCreatedFromTemplate ?metaTmplVal . } filter not exists { graph ?pi { ?np nt:wasCreatedFromTemplate ?metaOther . filter(str(?metaOther) < str(?metaTmplVal)) } } } bind(coalesce(?titleVal, ?labelVal, str(?version)) as ?Title) bind(replace(coalesce(?noteRaw, \"\"), \"\\r\", \"\") as ?noteNoCr) bind(if(contains(?noteNoCr, \"\\n\"), strbefore(?noteNoCr, \"\\n\"), ?noteNoCr) as ?firstLine) bind(substr(?firstLine, 1, 50) as ?Change_note) bind(concat(\"|\", coalesce(?winners, \"\"), \"|\") as ?wlist) bind(exists { graph npa:graph { ?sInv npx:invalidates ?np ; npx:supersedes ?np ; npa:hasValidSignatureForPublicKeyHash ?pubkeyhash . } } as ?isSuperseded) bind(exists { graph npa:graph { ?rInv npx:invalidates ?np ; npa:hasValidSignatureForPublicKeyHash ?pubkeyhash . filter not exists { ?rInv npx:supersedes ?np } } } as ?isRetracted) bind(bound(?space) && contains(?wlist, concat(\"|\", str(?_resource_multi_iri), \">\", str(?space), \">\", str(?Date), \">\", str(?np), \"|\")) as ?isCurrent) bind(if(?isCurrent, \"✓ current\", if(?isRetracted, \"retracted\", if(?isSuperseded, \"superseded\", \"\"))) as ?Status_noheader) bind(if(!?isCurrent && !?isRetracted, str(?np), \"\") as ?restore_target) bind(if(!?isCurrent && !?isRetracted, coalesce(str(?metaTmplVal), 'https://w3id.org/np/RALLhFXriQjVFESflcok4WIpBW5W0Zh9horxrvcACD1Mw/templateVersion'), \"\") as ?restore_template) bind(coalesce(str(?Author), \"\") as ?authorStr) bind(concat(\"|\", coalesce(?names, \"\"), \"|\") as ?nlist) bind(strbefore(strafter(?nlist, concat(\"|\", ?authorStr, \">\")), \"|\") as ?nameRaw) bind(if(?nameRaw != \"\", ?nameRaw, ?authorStr) as ?Author_label) bind(\"^\" as ?np_label) } order by desc(?Date)""" . } sub:provenance { sub:assertion prov:wasAttributedTo orcid:0000-0002-1267-0234; prov:wasDerivedFrom . } sub:pubinfo { orcid:0000-0002-1267-0234 foaf:name "Tobias Kuhn" . this: dct:created "2026-11-10T20:29:45Z"^^xsd:dateTime; dct:creator orcid:0000-0002-1267-0234; dct:license ; npx:embeds sub:get-view-version-history; rdfs:label "Get view version history"; nt:wasCreatedFromProvenanceTemplate ; nt:wasCreatedFromPubinfoTemplate , ; nt:wasCreatedFromTemplate . sub:sig npx:hasAlgorithm "RSA"; npx:hasPublicKey "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCwUtewGCpT5vIfXYE1bmf/Uqu1ojqnWdYxv+ySO80ul8Gu7m8KoyPAwuvaPj0lvPtHrg000qMmkxzKhYknEjq8v7EerxZNYp5B3/3+5ZpuWOYAs78UnQVjbHSmDdmryr4D4VvvNIiUmd0yxci47dTFUj4DvfHnGd6hVe5+goqdcwIDAQAB"; npx:hasSignature "gmPOF6dVgZ9+jb/PIcs2Gq5o3W9XQ//86F0a0/ktMh0yI1NH72WglkEBoDqjJYpo1FAYhEGvsUbFtu2EdvhQFgPalIUgXWk3keyTTWzyt6jvtN92Jre3ZoR0g1DiWl9ctys80BVogQ2J2+jTAT/dhtGRGjrvqMpYzK4/3lgxGWE="; npx:hasSignatureTarget this:; npx:signedBy orcid:0000-0002-1267-0234 . }