Skip to content

Wes/core architecture rework - #2638

Open
bwreid wants to merge 6 commits into
wes/draft-doc-optionfrom
wes/core-architecture-rework
Open

Wes/core architecture rework#2638
bwreid wants to merge 6 commits into
wes/draft-doc-optionfrom
wes/core-architecture-rework

Conversation

@bwreid

@bwreid bwreid commented Aug 4, 2026

Copy link
Copy Markdown

This PR breaks the Server page up into several different pages. The previous Server page has several different concepts within it, while this attempts to break it up into more manageable chunks that are a bit more readable and understandable. A general overview is below:


  • Overview — Frames the server as a thin coordination layer, not where logic lives. Compares agent-native's shape (server just does auth, migrations, and mounting actions) to a traditional app's (server holds business logic and data access). Points to Nitro/H3 as the underlying toolkit and links out to the other four pages plus a reminder to default to actions before writing custom routes.
    • Database — How to connect and use SQL. Covers the five hosting backends (SQLite default, PGlite for local Postgres, hosted Postgres/Neon/Supabase, Turso/libSQL, and a planned Builder.io-managed option), the three files every app needs (schema.ts, db/index.ts, plugins/db.ts), writing additive versioned migrations with runMigrations, scoping data with owner_email/ownableColumns()/accessFilter, the SQL-backed sync loop behind useDbSync(), and an escape hatch (getDbExec) for raw SQL.
    • Middleware — What server/middleware/ is and why the auth guard lives there instead of in a plugin (plugins only run at startup, not per-request, and the framework's own middleware registry doesn't cover page routes or custom /api/* routes). Shows the auth middleware file and how to add public paths via the auth plugin.
    • Plugins — Startup hooks in server/plugins/. Documents the two plugins every app ships (auth.ts, agent-chat.ts) plus the optional db.ts migrations plugin, how to write a custom plugin with defineNitroPlugin, and startup ordering (db → auth → agent-chat via alphabetical filename order).
    • Routes — File-based custom routes in server/routes/ vs. the framework-reserved /_agent-native/* namespace. Gives a decision table for when a custom route beats an action (webhooks, uploads, streaming, OAuth callbacks, public pages), a worked webhook example, naming conventions, how to scope a route to the request user with runWithRequestContext/accessFilter (since custom routes don't get auto request context like actions do), and the SSR catch-all route.

This does not yet include translations. I want to get this reviewed for content before spending the tokens on translations. :)

bwreid added 6 commits August 4, 2026 13:39
Adds five new draft MDX pages (server-overview, server-database,
server-middleware, server-plugins, server-routes) and an Agents
placeholder, wired into the nav under a draft Server group. Pages
are hidden in production and visible with VITE_SHOW_DRAFTS=true.

Includes nav keys in all locale files and an updated i18n doc-coverage
baseline to exempt draft pages from the localized-doc requirement.
Reframes db.ts as optional rather than default, moves the database
plugin section after auth and agent-chat, expands the intro to explain
what plugins are and how Nitro discovers them, and adds a new section
on writing custom plugins with defineNitroPlugin linking to Nitro docs.
…are guide

Expands the draft from a stub into a full page:
- Adds a diagram showing callers → middleware → allowed/blocked outcomes
- Rewrites the intro to describe middleware as a general cross-cutting layer
- Adds a "Writing Middleware" section with a defineEventHandler example and
  links to Nitro/H3 docs, placed before the auth section
- Consolidates The Auth Guard, Why Middleware, and Adding Public Paths under
  a single "The Auth Middleware" H2 with those as H3 subheadings
…agram

Reorganizes the draft from a loosely ordered reference into a narrative
that builds from concept to implementation:
- New diagram showing Browser/UI and Agent loop reaching the database
  through the same Actions layer
- Hosting Options section covering all five backends in order of
  complexity (SQLite default, PGlite, Postgres, Turso, Builder managed)
- Setting Up section as four numbered steps: define schema, create DB
  client, write migrations, query in actions
- Scoping Data to Users consolidates the owner_email and ownableColumns
  patterns that were previously scattered
- Removes all em-dashes throughout in favor of separate sentences
Ports the sync loop content from the published server.mdx into the
database page, where it completes the write story: after an action
mutates data, the sync version increments and useDbSync() on the client
invalidates caches so the UI refreshes. Includes the sync loop diagram
and the poll endpoint block. Adds a What's next link to real-time-sync.
Splits server.mdx into five pages (overview, database, middleware,
plugins, routes), un-drafts them in the nav, and repoints cross-page
links across the docs that pointed at the old combined page.
@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Here's a visual recap of what changed:

Visual recap

Open the full interactive recap

@builder-io-integration builder-io-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Builder reviewed your changes and found 2 potential issues 🔴

Review Details

Code Review Summary

This low-risk PR restructures the monolithic Server documentation page into focused Overview, Database, Middleware, Plugins, and Routes pages, adds a draft Agents entry, and updates the docs sidebar, cross-links, i18n labels, and localization coverage baseline. The overall information architecture is sound, and the new MDX blocks and primary English navigation paths were validated by the review agents. The main concern is migration safety for existing documentation URLs and correctness of newly introduced examples/links.

Key Findings

  • 🔴 HIGH — Two newly added visual/code blocks reuse globally existing IDs, which can cause block identity, rendering, or cache collisions.
  • 🔴 HIGH — The new Database page links to /docs/real-time-sync, which does not exist and returns 404.
  • 🟡 MEDIUM — Removing server.mdx without a server redirect breaks existing /docs/server links and bookmarks; HTTP verification confirmed a 404.
  • 🟡 MEDIUM — The webhook example can throw a 500 on malformed signature lengths because timingSafeEqual requires equal-length buffers.
  • 🟡 MEDIUM — The migration example uses SQLite-incompatible ADD COLUMN IF NOT EXISTS syntax despite documenting SQLite as the default backend.
  • 🟡 MEDIUM — The Agent Surfaces link now targets the agent-chat plugin but claims to provide the production handler’s full signature, which is no longer documented at that target.

The split itself is clear and the docs-block validation passed. 🧪 Browser testing: Attempted after this review; visual executors were unavailable, but HTTP checks confirmed the legacy /docs/server and /docs/real-time-sync failures.

| `now` | Dialect-agnostic current timestamp for `.default(now())` |

<DataModel
id="doc-block-14e70da"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 Use unique visual block IDs

This new DataModel reuses doc-block-14e70da, which already identifies the existing Database page's block. The duplicate global ID can cause the wrong block to be resolved or cached; assign a unique ID to each new block.

Additional Info
Found by code-review agent; corroborated by repository grep showing the same ID in packages/core/docs/content/database.mdx:159.

Fix in Builder

- [**Plugins**](/docs/server-plugins): the startup plugin lifecycle where migrations run
- [**Actions**](/docs/actions): the surface where actions call `getDb()` to read and write data
- [**Deployment**](/docs/deployment#persistent-database): connecting a persistent database per deploy target
- [**Real-Time Sync**](/docs/real-time-sync): `useDbSync()` and the full client-side sync model

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 Fix the broken Real-Time Sync link

/docs/real-time-sync has no corresponding documentation slug and returns 404. Point this link at the existing sync/collaboration documentation or add the missing page before publishing the new Database page.

Additional Info
Confirmed by repository search and HTTP verification from the browser-test planner.

Fix in Builder

@steve8708 steve8708 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

great stuff wes - may have some localized mdx we need to update/move too

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants