package graph import ( "context" "sourcecraft.dev/bigbes/sr-ht-dolt/browse" "sourcecraft.dev/bigbes/sr-ht-dolt/core" "sourcecraft.dev/bigbes/sr-ht-dolt/db" ) // The seams this package calls, declared consumer-side — the house style // web/deps.go sets and mcpsrv/ports.go repeats — so the schema can be exercised // over fakes, with no Postgres and no store on disk. // // What is absent from them is this schema's read-only design made structural // rather than remembered, exactly as on the MCP surface: no StoreManager, so // nothing here can create, move or delete a store; no repository create, update // or delete, and no ACL mutation, so the only writes dolt.sr.ht performs stay // behind the web UI; no key management, because a surface reached with one // credential has no business enumerating another; no SQL engine, because a bare // store has no working set to run one against. // // Adding a mutation to this schema therefore means widening this file first, // which is a diff a reviewer sees. // Repos is the metadata store as this schema reads it. // // It is spelled with db.Store's own signatures, so *db.Store satisfies it as // written and production binds it through the same request-scoped adapter web // and mcpsrv use. // // Visibility is not applied by GetRepoByOwnerAndName and must not be assumed // from it: what the caller may see is decided afterwards by core.Allowed over // the grant EffectiveAccess returns. The listings are the exception and carry // their rule in their own documentation. type Repos interface { // GetRepoByOwnerAndName resolves a database by its owner's username (no // leading "~") and name, or reports db.ErrNotFound. GetRepoByOwnerAndName(ctx context.Context, ownerUsername, name string) (*core.Repo, error) // ListReposForViewer lists every database viewer may be shown, across all // owners, newest first: PUBLIC to everyone, plus whatever viewer owns or // holds an ACL entry on. viewer is nil for an anonymous caller, and // anonymous is a normal caller here — it gets the PUBLIC set. ListReposForViewer(ctx context.Context, viewer *core.Caller) ([]*core.Repo, error) // ListReposByOwner is ListReposForViewer's rule narrowed to one owner. ListReposByOwner(ctx context.Context, ownerUsername string, viewer *core.Caller) ([]*core.Repo, error) // EffectiveAccess resolves the caller's ACL grant on a repository, or // (nil, nil) when there is none. A nil grant is not a denial: it is a // fall-through to visibility, which is what core.Allowed does with it. EffectiveAccess(ctx context.Context, userID, repoID int) (*core.AccessMode, error) // ListACL lists the grants on a repository. The schema exposes it to the // owner alone. ListACL(ctx context.Context, repoID int) ([]*db.ACLEntry, error) } // BrowseSession is the read-only view of one bare store this schema needs: a // strict subset of mcpsrv's, because rows and diffs are not published here. type BrowseSession interface { Branches(ctx context.Context) ([]browse.Branch, error) Log(ctx context.Context, refStr, fromHash string, limit int) ([]browse.CommitInfo, string, error) Tables(ctx context.Context, refStr string) ([]browse.TableInfo, error) Close() error } // BrowseOpener opens a session over the bare store at diskPath. Open is paired // with Close by the resolver that called it: a session is one fresh read of the // on-disk manifest, so nothing is cached between calls and a resolver sees the // commits a push landed a moment ago. type BrowseOpener interface { Open(ctx context.Context, diskPath string) (BrowseSession, error) }