package main import ( "context" "github.com/vaughan0/go-ini" "sourcecraft.dev/bigbes/sr-ht-dolt/browse" "sourcecraft.dev/bigbes/sr-ht-dolt/graph" "sourcecraft.dev/bigbes/sr-ht-dolt/web" ) // queryRoute is where the GraphQL schema answers. It is core-go's own path, // because that is where every SourceHut client — hut, api.sr.ht, meta's // personal-token page — already looks. The file beside it is served by // ecore's apimeta, at apimeta.Path. const queryRoute = "/query" // databaseScopeName is the one grant this service defines, spelled as // meta.sr.ht expects it: the part after the service name in // authn.DatabaseScope ("dolt.sr.ht/DATABASES"). meta prefixes the service name // itself. The two spellings are the same fact written twice, so a test asserts // them equal — a drift would let a user mint a token meta calls valid and this // service does not honour. // // meta reads this list once, at import time (metasrht/blueprints/oauth2.py), // and validates a requested grant against it verbatim. So changing it is a // two-sided deployment: this service ships the new name, and meta.sr.ht has to // be restarted before anyone can mint a token carrying it. const databaseScopeName = "DATABASES" // graphBrowseOpener satisfies graph.BrowseOpener over browse.Open, as // mcpBrowseOpener does for the MCP surface and web.BrowseAdapter for the pages: // one *browse.DB answers all three method sets, and each package declares the // seam it consumes rather than importing another's. type graphBrowseOpener struct{} var _ graph.BrowseOpener = graphBrowseOpener{} func (graphBrowseOpener) Open(ctx context.Context, diskPath string) (graph.BrowseSession, error) { dbh, err := browse.Open(ctx, diskPath) if err != nil { return nil, err } return dbh, nil } // newGraphServer assembles /query over the seams the daemon already has: the // same request-scoped metadata adapter the web pages and the MCP tools read // through, and the same bare-store reader. // // It shares /mcp's credential plane, validator included, so an instance that // runs no tokens.sr.ht refuses a working token on both surfaces and accepts // meta PATs and anonymous callers on both. Its failures are fatal for the same // reason /mcp's are: a surface that answers every query "could not be read" // because a seam was never wired is a daemon that starts and does not work. func newGraphServer(conf ini.File) (*graph.Server, error) { validator, err := newBearerValidator(conf) if err != nil { return nil, err } return graph.New(graph.Options{ Repos: web.DBAdapter{}, Browse: graphBrowseOpener{}, Validator: validator, }) }