Owner-only admin page: Reader roster plus Poll Lane status (#102) #107

Merged
sulthan merged 7 commits from feat/102-admin-page into main 2026-08-16 15:02:15 +07:00
5 changed files with 1067 additions and 992 deletions
Showing only changes of commit 2be9256e5e - Show all commits
+1 -1
View File
@@ -151,11 +151,11 @@
"150": "Reviewer Subagent (opencode)",
"151": "Finding Severity Rubric",
"152": "Spec Compliance Review",
"156": "ResponseWriter",
"161": "Why Use samber/oops",
"162": "singleflight Cache Stampede Prevention",
"163": "Struct Field Alignment",
"164": "testing/synctest Deterministic Goroutine Testing",
"165": "admin.go",
"177": "Backend CLAUDE.md Guidance",
"178": "Graphify Knowledge Graph (graphify-out/)",
"179": "CLAUDE.md (Symlink to AGENTS.md)",
+23 -23
View File
@@ -1,16 +1,16 @@
# Graph Report - mangaBookmark (2026-08-16)
## Corpus Check
- 116 files · ~283,317 words
- 116 files · ~284,419 words
- Verdict: corpus is large enough that graph structure adds value.
## Summary
- 1700 nodes · 3457 edges · 219 communities (69 shown, 150 thin omitted)
- Extraction: 91% EXTRACTED · 9% INFERRED · 0% AMBIGUOUS · INFERRED: 322 edges (avg confidence: 0.77)
- 1701 nodes · 3463 edges · 219 communities (69 shown, 150 thin omitted)
- Extraction: 91% EXTRACTED · 9% INFERRED · 0% AMBIGUOUS · INFERRED: 326 edges (avg confidence: 0.77)
- Token cost: 0 input · 0 output
## Graph Freshness
- Built from commit: `0b946ee2`
- Built from commit: `58014eb8`
- Run `git rev-parse HEAD` and compare to check if the graph is stale.
- Run `graphify update .` after code changes (no API cost).
@@ -45,8 +45,8 @@
- [[_COMMUNITY_Find Skills Guide|Find Skills Guide]]
- [[_COMMUNITY_Allocation Patterns|Allocation Patterns]]
- [[_COMMUNITY_Observability & Alerting|Observability & Alerting]]
- [[_COMMUNITY_AGENTS|AGENTS.md]]
- [[_COMMUNITY_Store|Store]]
- [[_COMMUNITY_Open|Open]]
- [[_COMMUNITY_Go Testing Guide|Go Testing Guide]]
- [[_COMMUNITY_Session Store|Session Store]]
- [[_COMMUNITY_Web UI Filter Logic|Web UI Filter Logic]]
@@ -166,11 +166,11 @@
- [[_COMMUNITY_Reviewer Subagent (opencode)|Reviewer Subagent (opencode)]]
- [[_COMMUNITY_Finding Severity Rubric|Finding Severity Rubric]]
- [[_COMMUNITY_Spec Compliance Review|Spec Compliance Review]]
- [[_COMMUNITY_ResponseWriter|ResponseWriter]]
- [[_COMMUNITY_Why Use samberoops|Why Use samber/oops]]
- [[_COMMUNITY_singleflight Cache Stampede Prevention|singleflight Cache Stampede Prevention]]
- [[_COMMUNITY_Struct Field Alignment|Struct Field Alignment]]
- [[_COMMUNITY_testingsynctest Deterministic Goroutine Testing|testing/synctest Deterministic Goroutine Testing]]
- [[_COMMUNITY_admin.go|admin.go]]
- [[_COMMUNITY_Backend CLAUDE.md Guidance|Backend CLAUDE.md Guidance]]
- [[_COMMUNITY_Graphify Knowledge Graph (graphify-out)|Graphify Knowledge Graph (graphify-out/)]]
- [[_COMMUNITY_CLAUDE.md (Symlink to AGENTS.md)|CLAUDE.md (Symlink to AGENTS.md)]]
@@ -235,12 +235,12 @@
- [[_COMMUNITY_Userscript CLAUDE guidance|Userscript CLAUDE guidance]]
## God Nodes (most connected - your core abstractions)
1. `testConfig()` - 53 edges
1. `testConfig()` - 54 edges
2. `newTestStore()` - 49 edges
3. `newWebTestServer()` - 49 edges
4. `newTestStore()` - 44 edges
5. `e()` - 33 edges
6. `Open()` - 29 edges
6. `Open()` - 30 edges
7. `Handler` - 29 edges
8. `Store` - 28 edges
9. `ne()` - 28 edges
@@ -276,7 +276,7 @@ Nodes (101): A(), ae(), an(), at(), B(), be(), bn(), bt() (+93 more)
### Community 1 - "Cover Fetch Test Helpers"
Cohesion: 0.09
Nodes (88): floatPtr(), testConfig(), getCover(), Cookie, Handler, ResponseRecorder, T, TestListRendersAcquiredCover() (+80 more)
Nodes (89): floatPtr(), testConfig(), getCover(), Cookie, Handler, ResponseRecorder, T, TestListRendersAcquiredCover() (+81 more)
### Community 2 - "Manga Userscript Adapters"
Cohesion: 0.06
@@ -368,7 +368,7 @@ Nodes (12): coverResponse(), Request, T, TestCoverFetcherCanonicalisesJpgAlias()
### Community 26 - "Open"
Cohesion: 0.05
Nodes (61): awaitPromise(), browserConnectionLost(), classifyBrowserError(), comixRead(), comixSeriesPageURL(), Action, Context, Mutex (+53 more)
Nodes (62): awaitPromise(), browserConnectionLost(), classifyBrowserError(), comixRead(), comixSeriesPageURL(), Action, Context, Mutex (+54 more)
### Community 27 - "Find Skills Guide"
Cohesion: 0.14
@@ -382,14 +382,14 @@ Nodes (14): Allocation Patterns, Backing Array Leaks, Direct indexing vs append,
Cohesion: 0.22
Nodes (9): Alerting rules (examples), CPU saturation, GC pressure, Goroutine leaks, Grafana Dashboards, Memory leaks, Prometheus Metrics for Go, PromQL Queries for Performance Diagnosis (+1 more)
### Community 31 - "Store"
Cohesion: 0.08
Nodes (9): CoverContentType(), coverRelativePath(), coverSourceAddress(), displayChapter(), Store, scanSeries(), TestDisplayChapter(), Bookmark (+1 more)
### Community 32 - "Open"
### Community 30 - "AGENTS.md"
Cohesion: 0.40
Nodes (5): Map of pointers for large, frequently updated structs, Memory Layout, Pointer receivers for large structs, Struct field alignment, Zero-size field at end of struct
### Community 31 - "Store"
Cohesion: 0.08
Nodes (8): coverRelativePath(), coverSourceAddress(), displayChapter(), Store, scanSeries(), TestDisplayChapter(), Bookmark, ReaderSummary
### Community 33 - "Go Testing Guide"
Cohesion: 0.20
Nodes (10): CI Regression Detection, Common Mistakes, Core Philosophy, Cross-References, Decision Tree: Where Is Time Spent?, Deep Dives, Go Performance Optimization, Iterative Optimization Methodology (+2 more)
@@ -534,7 +534,7 @@ Nodes (3): ADR-0005: On-demand browser sidecar, Constraints, Decision
Cohesion: 0.48
Nodes (6): T, TestCreateAndGetSession(), TestDeleteSessionIsPerReader(), TestDeleteSessionRevokes(), TestExpiredSessionIsGone(), TestGetSessionUnknownID()
### Community 165 - "admin.go"
### Community 156 - "ResponseWriter"
Cohesion: 0.18
Nodes (13): AdminPatterns(), HandlerFunc, Request, ResponseWriter, Time, Handler, readerPathID(), since() (+5 more)
@@ -550,14 +550,14 @@ Nodes (3): Live URL shapes (verified 2026-07-26, may drift — re-check against
## Suggested Questions
_Questions this graph is uniquely positioned to answer:_
- **Why does `New()` connect `Series Acquisition Tests` to `admin.go`, `Bookmarks API Tests`, `Cover & Acquire Internals`, `Session Middleware`, `Web UI Handlers`, `CDP Browser Client`?**
_High betweenness centrality (0.048) - this node is a cross-community bridge._
- **Why does `Open()` connect `CDP Browser Client` to `Cover Fetch Test Helpers`, `Series Acquisition Tests`, `Bookmarks API Tests`, `pgtest.go`, `Store Tests`, `Store`?**
_High betweenness centrality (0.046) - this node is a cross-community bridge._
- **Why does `newRouter()` connect `Bookmarks API Tests` to `Cover Fetch Test Helpers`, `Bookmarks API Handler`, `Series Acquisition Tests`, `admin.go`?**
_High betweenness centrality (0.032) - this node is a cross-community bridge._
- **Are the 47 inferred relationships involving `testConfig()` (e.g. with `TestListRendersAcquiredCover()` and `TestPublicCoverNeverEchoesNonImage()`) actually correct?**
_`testConfig()` has 47 INFERRED edges - model-reasoned connections that need verification._
_High betweenness centrality (0.050) - this node is a cross-community bridge._
- **Why does `New()` connect `Series Acquisition Tests` to `Bookmarks API Tests`, `Cover & Acquire Internals`, `Session Middleware`, `Web UI Handlers`, `CDP Browser Client`, `ResponseWriter`?**
_High betweenness centrality (0.048) - this node is a cross-community bridge._
- **Why does `newRouter()` connect `Bookmarks API Tests` to `Cover Fetch Test Helpers`, `Bookmarks API Handler`, `Series Acquisition Tests`, `ResponseWriter`?**
_High betweenness centrality (0.031) - this node is a cross-community bridge._
- **Are the 48 inferred relationships involving `testConfig()` (e.g. with `TestListRendersAcquiredCover()` and `TestPublicCoverNeverEchoesNonImage()`) actually correct?**
_`testConfig()` has 48 INFERRED edges - model-reasoned connections that need verification._
- **Are the 12 inferred relationships involving `newTestStore()` (e.g. with `TestAcquireDoesNotBlockTheWrite()` and `TestAcquireFailureLeavesTheBookmarkIntact()`) actually correct?**
_`newTestStore()` has 12 INFERRED edges - model-reasoned connections that need verification._
- **Are the 8 inferred relationships involving `newWebTestServer()` (e.g. with `TestListRendersAcquiredCover()` and `TestPublicCoverRejectsUnknownAddress()`) actually correct?**
File diff suppressed because one or more lines are too long
+1019 -944
View File
File diff suppressed because it is too large Load Diff
+20 -20
View File
@@ -170,8 +170,8 @@
"semantic_hash": "e51077b6a7f1f67afc748f1a32a1557d"
},
"backend/web_test.go": {
"mtime": 1786864334.8226542,
"ast_hash": "2e90ad82dcd9b1bbe4927681791541aa",
"mtime": 1786865248.7717106,
"ast_hash": "7c298e39c63e4502cf6272d1e206e9ef",
"semantic_hash": ""
},
"backend/main_test.go": {
@@ -220,8 +220,8 @@
"semantic_hash": ""
},
"docs/design-system.md": {
"mtime": 1786864602.4057882,
"ast_hash": "d82f3cd1fa19cbfb7f22917df655287f",
"mtime": 1786865139.9022946,
"ast_hash": "3bd39932997c8e245508874194db4e49",
"semantic_hash": ""
},
"backend/api_test.go": {
@@ -260,13 +260,13 @@
"semantic_hash": ""
},
"backend/internal/latest/poller.go": {
"mtime": 1786864207.0059254,
"ast_hash": "cf0f76b47dcc2ef33b4b2f87a1281dff",
"mtime": 1786865046.096795,
"ast_hash": "2bfb51177e3df474b80ea1b05523377e",
"semantic_hash": ""
},
"backend/internal/latest/poller_test.go": {
"mtime": 1786864054.5252442,
"ast_hash": "3f9843c15ef810c2ecad5c7928ef7fb0",
"mtime": 1786865291.3758123,
"ast_hash": "1da669ac748a8d1a0289e557392fa3fd",
"semantic_hash": ""
},
"backend/internal/latest/sites.go": {
@@ -425,13 +425,13 @@
"semantic_hash": "6c6f3e4c4c2f57867894280bce728c50"
},
"backend/AGENTS.md": {
"mtime": 1786864564.1525266,
"ast_hash": "25c96f73e7e45c3a84575d88ac850a2c",
"mtime": 1786865319.314815,
"ast_hash": "5bbabcd7dd425302cb0d989d8897baf6",
"semantic_hash": ""
},
"backend/CLAUDE.md": {
"mtime": 1786864564.1525266,
"ast_hash": "25c96f73e7e45c3a84575d88ac850a2c",
"mtime": 1786865319.314815,
"ast_hash": "5bbabcd7dd425302cb0d989d8897baf6",
"semantic_hash": ""
},
"backend/internal/web/templates/app.html": {
@@ -635,8 +635,8 @@
"semantic_hash": ""
},
"backend/internal/latest/status.go": {
"mtime": 1786864215.6331441,
"ast_hash": "32b82fdcd4673a0567f16e4a11a7962c",
"mtime": 1786865033.5648637,
"ast_hash": "8141514efa5a7a66e77b9a62d4982d52",
"semantic_hash": ""
},
"backend/internal/store/migrations/0010_reader_sightings.sql": {
@@ -645,18 +645,18 @@
"semantic_hash": ""
},
"backend/internal/web/admin.go": {
"mtime": 1786863809.8427207,
"ast_hash": "beae68aec5b21461fdecca855be6f67f",
"mtime": 1786865087.473256,
"ast_hash": "b1c0f23a102a9bc7f84adf306d743f56",
"semantic_hash": ""
},
"backend/internal/web/templates/admin.html": {
"mtime": 1786864471.1989238,
"ast_hash": "07038eaad03056e027e480900d5b8965",
"mtime": 1786865108.4095602,
"ast_hash": "f04ea1cb01369d53053eac489e796faa",
"semantic_hash": ""
},
"backend/internal/web/templates/lanes.html": {
"mtime": 1786863827.947877,
"ast_hash": "4ef59912aa68def6a378c25193fd052d",
"mtime": 1786865113.5362902,
"ast_hash": "8b9f9c7a56e0ec3bf950aa70acd95e92",
"semantic_hash": ""
}
}