---
title: "14: Capstone | SurrealDB University"
description: "Align with the docs project planning sample, baseline brownfield databases, and run schema across environments."
url: https://surrealdb.com/learn/schemas/page-14
---

![Course content preview](https://surrealdb.com/assets/static/course-schemas.D4CFbBhP.avif)

[Back to Courses](https://surrealdb.com/learn)

Course chapters

[Schema internals and migrations](https://surrealdb.com/learn/schemas) Internals [1: Schemaless vs. schemafull](https://surrealdb.com/learn/schemas/page-01) [2: Schema internals](https://surrealdb.com/learn/schemas/page-02) [3: Migrations](https://surrealdb.com/learn/schemas/page-03) [4: Data types](https://surrealdb.com/learn/schemas/page-04) [5: Automation](https://surrealdb.com/learn/schemas/page-05) Migrations [6: SurrealKit and the first table](https://surrealdb.com/learn/schemas/page-06) [7: Activities and seed data](https://surrealdb.com/learn/schemas/page-07) [8: Computed and asserted fields](https://surrealdb.com/learn/schemas/page-08) [9: Graph dependencies](https://surrealdb.com/learn/schemas/page-09) [10: Sync vs rollouts](https://surrealdb.com/learn/schemas/page-10) [11: Milestones](https://surrealdb.com/learn/schemas/page-11) [12: People and indexes](https://surrealdb.com/learn/schemas/page-12) [13: Events and CI](https://surrealdb.com/learn/schemas/page-13) [14: Capstone](https://surrealdb.com/learn/schemas/page-14)

# 14: Capstone

This chapter ties the course schema back to the published [project planning sample](https://surrealdb.com/docs/learn/schema-management/schema-design/sample-industry-schemas#project-planning), covers adopting SurrealKit on a database that already exists (brownfield), and rounds up how all the pieces fit together.

## Comparing against the docs sample

The docs page defines roughly the same shape:

| Piece | Purpose |
| --- | --- |
| `activity` | Scheduled work, `COMPUTED` `duration`, `ASSERT` progress, `COMPUTED` `followed_by` |
| `milestone` | Groups activities; `COMPUTED` `progress` / `is_complete`; `VALUE` `last_updated` |
| `depends_on` | `RELATION` activity → activity |
| `activity_of` | `RELATION` activity → project |
| `employee` | Optional `assigned_to` on activities |

Your `database/schema/` tree should look recognisably like this. A few things are intentionally different in the course version (`activity_audit`, `REFERENCE`, extra `indexes` and events), and that is fine. Write them down in a README next to the schema, so nobody wonders why your tables do not match the docs page line for line.

### Running a query from the sample

After seeding the docs example data:

```surql
-- Graph connections between activities and projects
SELECT *, ->?, <-? FROM activity, project;

-- Milestone roll-ups
SELECT name, progress, is_complete FROM milestone;
```

If your file layout looks different, run `INFO FOR DB` and compare it to the catalog the sample implies.

## Adopting a database that already exists

Not every project starts empty the way this course did. Imagine a database that has been growing for months in SurrealDB Studio and hand-written scripts, with no SurrealKit folder at all. You want rollouts going forward, but `rollout plan` needs something to diff *against*. An empty `database/snapshots/` would make the first plan look like “create the entire universe,” which is not what you want on a live host.

`rollout baseline` is the one-time “we start measuring from here” step for that situation.

### What baseline is for

1. You write `database/schema/*.surql` files so they mirror what is already live (export with `INFO FOR DB` / `INFO FOR TABLE`, or the helper query in the [existing databases](https://surrealdb.com/docs/manage/schema-migration/getting-started/existing-databases) docs).
2. You run:

```bash
surrealkit rollout baseline --user root --pass secret --ns main --db main
```

```text
Seeded managed entity baseline with 9 schema file(s) and 36 managed object(s).
```

3. SurrealKit records that agreed starting point:
   - Snapshot files under `database/snapshots/` (`schema_snapshot.json`, `catalog_snapshot.json`) - this is what later `rollout plan` diffs against
   - SurrealKit bookkeeping in the database (`__entity` and related metadata), so sync/rollouts know which objects are managed

After that, you edit schema files as usual. The next `rollout plan` only contains the changes since the baseline (or since the last plan that refreshed those snapshots), not a full rebuild of every table. Run one straight after a baseline and the manifest is empty, which is the signal that files and database agree:

```toml
source_schema_hash = "d48709463f2c1c2732bb9d86343858a88a5103baefe76f5769d0e426b7544a22"
target_schema_hash = "d48709463f2c1c2732bb9d86343858a88a5103baefe76f5769d0e426b7544a22"
compatibility = "phased"
renames = []
steps = []
```

Think of it as zeroing the odometer for SurrealKit: “everything already in production is accounted for; only new edits become migration steps.”

Note

Baseline is a brownfield adoption command. It is meant to run once on a database that does not already have SurrealKit rollout state. Your course database has already been through `sync` and `rollouts`, so running it there fails on purpose:

Practise the idea on a separate throwaway instance, or treat this section as reference for the day you adopt a legacy DB.

### After baseline

The ongoing loop is the one you already know:

1. Keep `database/schema/*.surql` as the source of truth (reconcile anything baseline found that you had missed)
2. Iterate with `sync` on a local, disposable database
3. `rollout plan` for the next shared change, and commit the manifest
4. CI, or an operator with shared-database credentials, runs `start`, deploys, then `complete`

Part [2](https://surrealdb.com/learn/schemas/page-02)'s `INFO FOR TABLE` export, and `(INFO FOR TABLE t).{ statements: fields + indexes }.statements.values()`, are still useful for sketching those first schema files from a live catalog.

Commit the snapshots with the SurrealKit folder so every teammate (and CI) plans against the same baseline.

## Environments

| Environment | Typical command | Credentials |
| --- | --- | --- |
| Local dev | `sync --watch` | Local `.env`, pointed at a disposable DB only |
| CI checks | `test` (ephemeral DB; sync underneath is fine) | A CI service account for a throwaway instance |
| Staging / production apply | `rollout start` / `complete`, with a reviewed, committed manifest | CI or a secret manager, never your laptop's `sync` `.env` |

Namespace and database names often differ between environments (`dev` vs `prod`), while the schema files stay identical. Until SurrealKit is wired into CI, give shared environments their own connection settings, and lean on `rollout` there. Do not let `sync` become the default for every environment once other data or services depend on it.

See also [sync vs rollouts](https://surrealdb.com/docs/manage/schema-migration/getting-started/sync-vs-rollouts).

## A few extras from the sample page

The industry schemas page groups other patterns you could bolt on as stretch goals:

| Pattern | Where it appears |
| --- | --- |
| SCADA-style `DEFINE EVENT` and time-series | Sensor indexes, composite record IDs |
| Risk `UNIQUE` `index` | `(project, description)` |
| Supply chain `COMPUTED` totals | Financial roll-ups, similar to milestone `progress` |

The planning domain has already exercised graph, `COMPUTED`, indexes, and events. The same migration discipline carries over to whichever of these you try next.

## Generating types

Once the catalog has settled, you can generate application types straight from it:

```bash
surrealkit typegen
```

```text
typegen: wrote ./database/types/schema.json
```

By default this introspects the live database and writes a JSON schema document, which is the format other tooling reads. To get TypeScript interfaces instead, point `surrealkit.toml` at an output directory:

```toml
[typegen]
typescript = "../src/types"
format     = "biome check --write"   # optional, runs on the generated file
```

With that set, `typegen` (and `sync --watch`) write an `index.ts` of typed table interfaces there. Literal unions on status-like fields turn into proper typed unions in TypeScript, which is one more reason to reach for `TYPE 'todo' | 'doing' | 'done'` instead of `string` plus `ASSERT` (part [4](https://surrealdb.com/learn/schemas/page-04)).

See [type generation](https://surrealdb.com/docs/manage/schema-migration/typegen) for details.

## Where to go from here

- [SurrealKit documentation](https://surrealdb.com/docs/manage/schema-migration)
- [SurrealKit templates](https://github.com/surrealdb/surrealkit#templates), for what `init` adds when you skip `--minimal` (Organizations, Teams, custom `--from` templates)
- [Sample industry schemas](https://surrealdb.com/docs/learn/schema-management/schema-design/sample-industry-schemas), for project planning plus peer examples
- [Schema evolution](https://surrealdb.com/docs/learn/schema-management/schema-design/schema-evolution), for data migrations alongside catalog changes
- Course sketches, Gel-inspired patterns you can merge or delete

You now have a version-controlled path from an empty database to a graph-shaped planning schema: `sync` for disposable local databases, `test` in CI, and `rollouts` (planned locally, applied with shared-environment secrets) whenever the database is shared.

Previous

13: Events and CI

[Previous](https://surrealdb.com/learn/schemas/page-13)

```json
{"@context":"https://schema.org","@type":"Course","name":"Schema internals and migrations","description":"Learn how SurrealDB stores schema metadata, how DEFINE statements shape your database, and how to migrate production data safely.","url":"https://surrealdb.com/learn/schemas","inLanguage":"en","isAccessibleForFree":true,"provider":{"@type":"Organization","name":"SurrealDB","url":"https://surrealdb.com"},"hasPart":[{"@type":"LearningResource","name":"Schema internals and migrations","url":"https://surrealdb.com/learn/schemas"},{"@type":"LearningResource","name":"1: Schemaless vs. schemafull","url":"https://surrealdb.com/learn/schemas/page-01"},{"@type":"LearningResource","name":"2: Schema internals","url":"https://surrealdb.com/learn/schemas/page-02"},{"@type":"LearningResource","name":"3: Migrations","url":"https://surrealdb.com/learn/schemas/page-03"},{"@type":"LearningResource","name":"4: Data types","url":"https://surrealdb.com/learn/schemas/page-04"},{"@type":"LearningResource","name":"5: Automation","url":"https://surrealdb.com/learn/schemas/page-05"},{"@type":"LearningResource","name":"6: SurrealKit and the first table","url":"https://surrealdb.com/learn/schemas/page-06"},{"@type":"LearningResource","name":"7: Activities and seed data","url":"https://surrealdb.com/learn/schemas/page-07"},{"@type":"LearningResource","name":"8: Computed and asserted fields","url":"https://surrealdb.com/learn/schemas/page-08"},{"@type":"LearningResource","name":"9: Graph dependencies","url":"https://surrealdb.com/learn/schemas/page-09"},{"@type":"LearningResource","name":"10: Sync vs rollouts","url":"https://surrealdb.com/learn/schemas/page-10"},{"@type":"LearningResource","name":"11: Milestones","url":"https://surrealdb.com/learn/schemas/page-11"},{"@type":"LearningResource","name":"12: People and indexes","url":"https://surrealdb.com/learn/schemas/page-12"},{"@type":"LearningResource","name":"13: Events and CI","url":"https://surrealdb.com/learn/schemas/page-13"},{"@type":"LearningResource","name":"14: Capstone","url":"https://surrealdb.com/learn/schemas/page-14"}]}
```

```json
{"@context":"https://schema.org","@type":"LearningResource","name":"14: Capstone","description":"Align with the docs project planning sample, baseline brownfield databases, and run schema across environments.","url":"https://surrealdb.com/learn/schemas/page-14","learningResourceType":"lesson","isPartOf":{"@type":"Course","name":"Schema internals and migrations","url":"https://surrealdb.com/learn/schemas"},"position":17}
```

```json
{"@context":"https://schema.org","@type":"Organization","name":"SurrealDB","url":"https://surrealdb.com","logo":"https://surrealdb.com/assets/static/logo.BG7_TG2b.svg","description":"SurrealDB is the unified data layer for AI. A multi-model database for documents, graphs, vectors, and time-series.","foundingDate":"2022","legalName":"SurrealDB Ltd","identifier":{"@type":"PropertyValue","propertyID":"GB-COH","value":"13615201"},"address":{"@type":"PostalAddress","streetAddress":"3rd Floor, 1 Ashley Road","addressLocality":"Altrincham","addressRegion":"Cheshire","postalCode":"WA14 2DT","addressCountry":"GB"},"contactPoint":[{"@type":"ContactPoint","contactType":"customer support","email":"support@surrealdb.com","url":"https://surrealdb.com/contact","availableLanguage":"English"},{"@type":"ContactPoint","contactType":"sales","email":"info@surrealdb.com","url":"https://surrealdb.com/contact","availableLanguage":"English"},{"@type":"ContactPoint","contactType":"security","email":"security@surrealdb.com","url":"https://surrealdb.com/.well-known/security.txt","availableLanguage":"English"},{"@type":"ContactPoint","contactType":"legal","email":"legal@surrealdb.com","url":"https://surrealdb.com/legal","availableLanguage":"English"}],"hasCertification":[{"@type":"Certification","name":"SOC 2 Type 2"},{"@type":"Certification","name":"GDPR"},{"@type":"Certification","name":"Cyber Essentials Plus"},{"@type":"Certification","name":"ISO 27001"}],"owns":[{"@type":"SoftwareApplication","name":"SurrealDB","url":"https://surrealdb.com/surrealdb"},{"@type":"SoftwareApplication","name":"Agent Memory","url":"https://surrealdb.com/agent-memory"}],"knowsAbout":["multi-model databases","document databases","graph databases","vector search","time-series databases","SurrealQL","Agent Memory","real-time databases","embedded databases","context layer","graph ontology","distributed database","knowledge graphs","distributed transaction protocols","highly-scalable databases"],"sameAs":["https://www.wikidata.org/wiki/Q124316308","https://github.com/surrealdb/surrealdb","https://twitter.com/surrealdb","https://www.youtube.com/@surrealdb","https://www.linkedin.com/company/surrealdb","https://discord.gg/surrealdb","https://www.reddit.com/r/surrealdb","https://www.instagram.com/surrealdb","https://medium.com/surrealdb","https://dev.to/surrealdb"]}
```

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://surrealdb.com"},{"@type":"ListItem","position":2,"name":"Learn","item":"https://surrealdb.com/learn"},{"@type":"ListItem","position":3,"name":"Page 14","item":"https://surrealdb.com/learn/schemas/page-14"}]}
```
