sx-gitea Phase 4: issues — content-document bodies + relations graph (TDD, 360/360)
lib/gitea/issues.sx: issues as kv records (zero-padded per-repo numbering, title/author/state, sorted label+assignee sets, Markdown body, comment thread). Bodies and comments are content-on-sx documents: content/from-markdown -> block doc -> content/html for pages, with the round-trip law asserted in the suite. The issue graph (issue->repo parent, author origin, assignee member, label link, commenter reply) is DERIVED into lib/relations facts and rebuilt on fact change — same pattern as the acl db, so deleting a repo can never dangle edges. Views: open/closed/by-label/by-assignee; graph queries: repo-issue-nodes, user-authored, user-assigned, label-issues, issue-participants. Web: issues list + issue page (rendered HTML body + comments), JSON API: create (any authenticated reader), comment, close/reopen (author or write), label/assignee management (write). All read-gated like the rest. Infra: gitea/route-packs registry — wire/issues append their routes at load; gitea/app serves all packs. repo-delete! now purges collab/issue/ issue-seq rows too (ghost-state regression tested). Conformance runner gains per-suite extra modules; the issues suite loads relations + smalltalk + content (~5s). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -145,7 +145,24 @@
|
||||
(forge owner name)
|
||||
(git/repo-named (gitea/forge-db forge) (gitea/repo-ns owner name))))
|
||||
|
||||
; delete the record and purge every git key under the repo's namespace
|
||||
; everything owned by a repo record, beyond the record itself: its git
|
||||
; namespace and any per-repo rows other phases hang off it
|
||||
(define
|
||||
gitea/repo-purge-prefixes
|
||||
(fn
|
||||
(owner name)
|
||||
(list
|
||||
(str (gitea/repo-ns owner name) "/")
|
||||
(str "gitea/collab/" owner "/" name "/")
|
||||
(str "gitea/issue/" owner "/" name "/"))))
|
||||
|
||||
(define
|
||||
gitea/repo-purge-keys
|
||||
(fn (owner name) (list (str "gitea/issue-seq/" owner "/" name))))
|
||||
|
||||
; delete the record and purge every key the repo owns — a recreated repo
|
||||
; under the same name must start truly empty (no ghost collaborators,
|
||||
; issues, or objects)
|
||||
(define
|
||||
gitea/repo-delete!
|
||||
(fn
|
||||
@@ -154,15 +171,25 @@
|
||||
(not (gitea/repo-exists? forge owner name))
|
||||
false
|
||||
(let
|
||||
((db (gitea/forge-db forge)))
|
||||
(let
|
||||
((pfx (str (gitea/repo-ns owner name) "/")))
|
||||
(begin
|
||||
(for-each
|
||||
(fn (k) (persist/kv-delete db k))
|
||||
(filter (fn (k) (starts-with? k pfx)) (persist/kv-keys db)))
|
||||
(persist/kv-delete db (gitea/repo-key owner name))
|
||||
true))))))
|
||||
((db (gitea/forge-db forge))
|
||||
(prefixes (gitea/repo-purge-prefixes owner name)))
|
||||
(begin
|
||||
(for-each
|
||||
(fn
|
||||
(k)
|
||||
(if
|
||||
(reduce
|
||||
(fn (acc p) (or acc (starts-with? k p)))
|
||||
false
|
||||
prefixes)
|
||||
(persist/kv-delete db k)
|
||||
nil))
|
||||
(persist/kv-keys db))
|
||||
(for-each
|
||||
(fn (k) (persist/kv-delete db k))
|
||||
(gitea/repo-purge-keys owner name))
|
||||
(persist/kv-delete db (gitea/repo-key owner name))
|
||||
true)))))
|
||||
|
||||
(define gitea/repos (fn (forge) (gitea/names-under forge "gitea/repo/")))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user