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.
Backend
Section titled “Backend”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
Section titled “Dashboard”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
Section titled “Packages”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.
Architecture rules
Section titled “Architecture rules”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.
Repository docs
Section titled “Repository docs”| 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. |