From f809f660f4fe389a9778cff6ebdd474f66ade975 Mon Sep 17 00:00:00 2001 From: Alex Date: Mon, 22 Jun 2026 23:33:47 +0100 Subject: [PATCH] fix(wiki): maintain sources.tokens for wikis (sum of page token_counts) sources.tokens was only set at ingest, so wikis showed no/stale token count on the card (blank wikis showed nothing; converted ones showed the stale original count). rebuild_wiki_directory_structure (called after every wiki mutation) now also sets sources.tokens to the sum of wiki_pages.token_count; blank wiki create sets tokens=0. So the card reflects live wiki content. --- application/api/user/sources/routes.py | 1 + .../storage/db/repositories/wiki_pages.py | 3 +- tests/api/user/sources/test_wiki_routes.py | 4 +++ .../db/repositories/test_wiki_pages.py | 35 +++++++++++++++++++ 4 files changed, 42 insertions(+), 1 deletion(-) diff --git a/application/api/user/sources/routes.py b/application/api/user/sources/routes.py index d5d98b0d..b1f6e15b 100644 --- a/application/api/user/sources/routes.py +++ b/application/api/user/sources/routes.py @@ -763,6 +763,7 @@ class CreateWikiSource(Resource): type="wiki", config={"kind": "wiki"}, directory_structure={}, + tokens=0, ) if initial_content: WikiPagesRepository(conn).upsert( diff --git a/application/storage/db/repositories/wiki_pages.py b/application/storage/db/repositories/wiki_pages.py index fcb07233..8ad378ae 100644 --- a/application/storage/db/repositories/wiki_pages.py +++ b/application/storage/db/repositories/wiki_pages.py @@ -249,7 +249,8 @@ def rebuild_wiki_directory_structure( pages = WikiPagesRepository(conn).list_for_source(source_id) tree = build_wiki_directory_structure(pages) + total_tokens = sum(int(page.get("token_count") or 0) for page in pages) SourcesRepository(conn).update( - source_id, owner_id, {"directory_structure": tree} + source_id, owner_id, {"directory_structure": tree, "tokens": total_tokens} ) return tree diff --git a/tests/api/user/sources/test_wiki_routes.py b/tests/api/user/sources/test_wiki_routes.py index 3c08ea90..f3a7303c 100644 --- a/tests/api/user/sources/test_wiki_routes.py +++ b/tests/api/user/sources/test_wiki_routes.py @@ -94,6 +94,7 @@ class TestCreateWikiSource: row = SourcesRepository(pg_conn).get_any(source_id, user) assert row["type"] == "wiki" assert row["config"]["kind"] == "wiki" + assert int(row["tokens"]) == 0 # No seed content → no re-embed, and never any ingest/reingest task. mock_reembed.assert_not_called() mock_ingest.assert_not_called() @@ -105,6 +106,7 @@ class TestCreateWikiSource: WikiPage, WIKI_INDEX_PATH, ) + from application.storage.db.repositories.sources import SourcesRepository user = "u-wiki-seed" with _patch_db(pg_conn), patch( @@ -124,6 +126,8 @@ class TestCreateWikiSource: assert response.status_code == 200 source_id = response.json["source_id"] + row = SourcesRepository(pg_conn).get_any(source_id, user) + assert int(row["tokens"]) > 0 # Re-embed fires once, only for the seed page; no ingest/reingest ever. mock_reembed.assert_called_once() assert mock_reembed.call_args.args[0] == source_id diff --git a/tests/storage/db/repositories/test_wiki_pages.py b/tests/storage/db/repositories/test_wiki_pages.py index 721a135e..4dd4d5a7 100644 --- a/tests/storage/db/repositories/test_wiki_pages.py +++ b/tests/storage/db/repositories/test_wiki_pages.py @@ -239,6 +239,41 @@ class TestDirectoryStructure: stored = SourcesRepository(pg_conn).get(sid, "rebuild-user") assert "a.md" in (stored["directory_structure"] or {}) + def test_rebuild_sets_source_tokens_to_sum(self, pg_conn): + repo = _repo(pg_conn) + owner = "rebuild-tokens-user" + sid = str( + SourcesRepository(pg_conn).create( + "rebuild-tokens-src", user_id=owner, type="wiki" + )["id"] + ) + page_a = repo.upsert(sid, "/a.md", "alpha beta gamma") + page_b = repo.upsert(sid, "/dir/b.md", "delta epsilon") + expected = page_a["token_count"] + page_b["token_count"] + + rebuild_wiki_directory_structure(pg_conn, sid, owner) + + stored = SourcesRepository(pg_conn).get(sid, owner) + assert int(stored["tokens"]) == expected + + def test_rebuild_after_delete_lowers_source_tokens(self, pg_conn): + repo = _repo(pg_conn) + owner = "rebuild-delete-user" + sid = str( + SourcesRepository(pg_conn).create( + "rebuild-delete-src", user_id=owner, type="wiki" + )["id"] + ) + page_a = repo.upsert(sid, "/a.md", "alpha beta gamma") + repo.upsert(sid, "/b.md", "delta epsilon") + rebuild_wiki_directory_structure(pg_conn, sid, owner) + + repo.delete_by_path(sid, "/b.md") + rebuild_wiki_directory_structure(pg_conn, sid, owner) + + stored = SourcesRepository(pg_conn).get(sid, owner) + assert int(stored["tokens"]) == page_a["token_count"] + class TestSetEmbedStatus: def test_set_embed_status(self, pg_conn):