feat: model inbox capture artifacts

This commit is contained in:
2026-06-05 01:40:08 +08:00
parent 2e86229350
commit d6ef3a973a
10 changed files with 108 additions and 17 deletions
+33 -2
View File
@@ -1,6 +1,12 @@
package main
func (a *App) ListInboxNodes() ([]NodeDTO, error) {
type InboxNodeDTO struct {
NodeDTO
CaptureKind string `json:"captureKind"`
CaptureSource string `json:"captureSource"`
}
func (a *App) ListInboxNodes() ([]InboxNodeDTO, error) {
if err := a.requireVault(); err != nil {
return nil, err
}
@@ -8,7 +14,17 @@ func (a *App) ListInboxNodes() ([]NodeDTO, error) {
if err != nil {
return nil, err
}
dtos := toNodeDTOs(list)
dtos := make([]InboxNodeDTO, 0, len(list))
for _, n := range list {
dto := InboxNodeDTO{NodeDTO: toNodeDTO(&n)}
if kind, ok, err := a.nodes.MetaGet(n.ID, "capture.kind"); err == nil && ok {
dto.CaptureKind = kind
}
if source, ok, err := a.nodes.MetaGet(n.ID, "capture.source"); err == nil && ok {
dto.CaptureSource = source
}
dtos = append(dtos, dto)
}
for i := range dtos {
n, err := a.nodes.CountChildren(dtos[i].ID, "case", "client", "project", "folder", "document", "recipe")
if err != nil {
@@ -18,3 +34,18 @@ func (a *App) ListInboxNodes() ([]NodeDTO, error) {
}
return dtos, nil
}
func (a *App) filterInboxCaptureNodes(list []NodeDTO) []NodeDTO {
out := make([]NodeDTO, 0, len(list))
for _, item := range list {
if !a.isInboxCaptureNode(item.ID) {
out = append(out, item)
}
}
return out
}
func (a *App) isInboxCaptureNode(nodeID string) bool {
v, ok, err := a.nodes.MetaGet(nodeID, "capture.inbox")
return err == nil && ok && v == "true"
}
+7 -7
View File
@@ -22,7 +22,7 @@ func (a *App) ListWorkspaceTree() ([]NodeDTO, error) {
if err != nil {
return nil, err
}
dtos := filterContainers(toNodeDTOs(list))
dtos := filterContainers(a.filterInboxCaptureNodes(toNodeDTOs(list)))
for i := range dtos {
n, err := a.nodes.CountChildren(dtos[i].ID, "case", "client", "project", "folder", "document", "recipe")
if err != nil {
@@ -41,7 +41,7 @@ func (a *App) ListWorkspaceChildren(parentID string) ([]NodeDTO, error) {
if err != nil {
return nil, err
}
dtos := filterContainers(toNodeDTOs(list))
dtos := filterContainers(a.filterInboxCaptureNodes(toNodeDTOs(list)))
for i := range dtos {
n, err := a.nodes.CountChildren(dtos[i].ID, "case", "client", "project", "folder", "document", "recipe")
if err != nil {
@@ -778,11 +778,11 @@ func (a *App) moveFolderNode(nodeID string, node *nodes.Node, parent *nodes.Node
func (a *App) moveNoteFileNode(nodeID string, node *nodes.Node, parent *nodes.Node, newParentID, nodeTitle string, titleChanged bool) error {
// Collect file records before any mutations.
type fileMove struct {
id string
oldPath string
oldAbs string
newRelPath string
newAbs string
id string
oldPath string
oldAbs string
newRelPath string
newAbs string
}
var fileMoves []fileMove
frows, ferr := a.db.Query(`SELECT id, path FROM files WHERE node_id=?`, nodeID)
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -16,7 +16,7 @@
background: #13131f;
}
</style>
<script type="module" crossorigin src="/assets/main-O6a-DCWF.js"></script>
<script type="module" crossorigin src="/assets/main-meJOE1Ze.js"></script>
<link rel="stylesheet" crossorigin href="/assets/main-es_E5H-H.css">
</head>
<body>
+26
View File
@@ -27,6 +27,12 @@ func TestListInboxNodesReturnsOnlyCapturedArtifacts(t *testing.T) {
if err := app.nodes.MetaSet(captured.ID, "capture.inbox", "true"); err != nil {
t.Fatalf("mark captured: %v", err)
}
if err := app.nodes.MetaSet(captured.ID, "capture.kind", "text"); err != nil {
t.Fatalf("mark capture kind: %v", err)
}
if err := app.nodes.MetaSet(captured.ID, "capture.source", "clipboard"); err != nil {
t.Fatalf("mark capture source: %v", err)
}
list, err := app.ListInboxNodes()
if err != nil {
@@ -40,6 +46,16 @@ func TestListInboxNodesReturnsOnlyCapturedArtifacts(t *testing.T) {
if !got[captured.ID] {
t.Fatal("captured artifact missing from inbox")
}
for _, item := range list {
if item.ID == captured.ID {
if item.CaptureKind != "text" {
t.Fatalf("CaptureKind = %q, want text", item.CaptureKind)
}
if item.CaptureSource != "clipboard" {
t.Fatalf("CaptureSource = %q, want clipboard", item.CaptureSource)
}
}
}
if got[manual.ID] {
t.Fatal("manual root should not be in inbox")
}
@@ -49,4 +65,14 @@ func TestListInboxNodesReturnsOnlyCapturedArtifacts(t *testing.T) {
if got[child.ID] {
t.Fatal("nested child should not be in inbox")
}
workspace, err := app.ListWorkspaceTree()
if err != nil {
t.Fatalf("ListWorkspaceTree: %v", err)
}
for _, item := range workspace {
if item.ID == captured.ID {
t.Fatal("captured artifact should not be shown in workspace tree")
}
}
}