Skip to content

Codebase map

Every module under src/ has its own ARCHITECTURE.md. Read it before editing that module, and update it when the module’s files or invariants change.

One folder per domain, each with a service.ts and co-located *.test.ts.

Path What
src/http/server.ts The single fetch handler. route() dispatches every path. src/index.ts boots it.
src/projects/ factory.ts builds a project’s full service stack; resolver.ts routes by id or slug.
src/auth/ End-user auth and JWTs.
src/control/ The control plane: projects, members, token exchange.
src/data/ DocumentService — policy-gated CRUD. store.ts is the ungated DataStore port.
src/authz/ permissions.ts (can() and permission strings) · engine.ts (policy filter injection) · policy.ts (AuthContext and the rule DSL) · cel.ts (the hardened CEL-subset evaluator) · registry.ts and validate.ts (policy store and definition-time checks) · roles.ts and enduser-roles.ts (role registries)
src/schema/ validate.ts — the JSON-Schema subset: definition allowlist plus document validation.
src/functions/ service.ts (triggers, including http) · runner.ts / worker.ts (the sandboxed Bun Worker pool and the ctx.db RPC bridge) · http-routes.ts (the custom-endpoint matcher)
src/graphql/ Per-project GraphQL — generic plus typed-from-schema. Every resolver goes through DocumentService.
src/adapters/ mongo/ implements the ports (integration-tested only with MONGO_URL); s3/ is the S3-compatible BlobStore.
src/mcp/ The MCP admin server over stdio: client.ts, tools/*.ts, guide.ts, index.ts.
src/sdk/ The end-user client SDK.
src/cli/ The grove CLI. Raw fetch like the MCP — it never imports the SDK or the server.
src/testkit/ The dev-facing unit-test harness for functions. Type-only imports from functions/; must stay plain-Node compatible.
src/config/ Export, plan and import — plus bundle.ts, the pure projection to and from the on-disk bundle.
src/introspect/ BYO-Mongo sampling, schema inference and import.

Plus collections/, users/, apikeys/, storage/, audit/, roles/, enduser-roles/, vector/, realtime/, webhooks/, integrations/, connections/, billing/, usage/.

dashboard/ — React, Vite and shadcn/ui, with its own Vitest suite. Sections live in dashboard/src/views/sections/. The API client is dashboard/src/lib/api.ts, exporting project (aliased call) for project-scoped routes and control for the control plane.

packages/ holds packaging shells only — the source never moves out of src/.

Package Bin / entry Source
@groveback/cli grove src/cli/
@groveback/sdk ESM, browser target src/sdk/client.ts
@groveback/testkit ESM, node target src/testkit/
@groveback/mcp groveback-mcp src/mcp/
@groveback/server groveback the whole backend, compiled per platform

@groveback/server publishes standalone binaries, one npm package per platform, declared as optionalDependencies with os/cpu constraints — so an install pulls only the matching one. Its bin.js is plain Node, because the binary carries its own Bun runtime.

Baked into each binary: the function worker pre-built to JS (an embedded .ts asset would be served unparsed), the built dashboard with a content-hashed manifest, and the version.

These must hold. They are the invariants the tests and reviews check for.

Authorization is permission-based. The engine gates on data:<collection>:<op> permissions, not a legacy rule.roles field. An admin API-key scope maps to permissions ['*'] and reaches everything. Member roles and end-user roles are separate namespaces (__roles versus __enduser_roles), and end-user roles accept data-plane permissions only.

The data plane is fail-closed. No policy means non-admin access is denied. The admin browser routes (/admin/collections/:name/documents) bypass policy deliberately and are admin-gated.

Functions run sandboxed. The Worker has no Mongo client and no secrets; functions reach the database only through the host-mediated ctx.db RPC bridge in runner.ts. Every post run gets it — http, events, manual — and pre hooks never do. Never give the worker a real client.

The MCP mirrors the REST API by raw fetch. It never imports server internals.

System collections (__*, and the names in src/core/reserved.ts) are off the data and collections APIs.

File Role
CLAUDE.md The repo guide for agents — layout, rules, commands, conventions.
PROGRESS.md Current work state. Update at session end.
DECISIONS.md Append-only decision log. Add an entry when an architectural choice is made.
product.md The PRD and design notes.
docs/*.md Design documents — authorization, data model, hooks, OAuth, BYO Mongo, config versioning.
docs/site/ This documentation site.
Makefile Every development command.