|
1 | 1 | # Oracle Notes |
2 | 2 |
|
3 | | -A bright, deliberately small Typegres application: username/password login and private CRUD notes, backed by Oracle Database 23. The browser authors type-safe queries over Cap'n Web's HTTP batch transport; every operation logs in and receives a freshly hydrated `Users` row capability. |
| 3 | +This is a deliberately small notes app running on Oracle Database 23. The app itself is basic: create notes, edit them, and delete them. The interesting part is how it is implemented. |
4 | 4 |
|
5 | | -`Users.notes()` follows a `Relation.has` edge. Edits and deletes narrow that relation by ID, obtain one `Note` capability, and invoke its capability method. Note IDs remain query data rather than arguments to application RPC methods. |
| 5 | +## The data model is the API |
| 6 | + |
| 7 | +In Typegres, the backend data model is also the application API. The model in [`server/api.ts`](server/api.ts) has only two tables: `Users` and `Notes`. Members are selectively exposed as capabilities. A note exposes the fields the browser needs, while a user never exposes `password_hash`. |
| 8 | + |
| 9 | +The browser starts with a root `Api` capability. Each HTTP batch logs in and pipelines the resulting `Users` capability through the rest of the operation. From that user, the browser can follow `Users.notes()`, a `Relation.has` edge containing only that user's notes. |
| 10 | + |
| 11 | +The browser then composes ordinary typed query operations over the relation it can reach. For example, the notes list adds `orderBy()` and `select()` on the frontend. That query expression travels over Cap'n Web RPC, Typegres compiles it on the server, and Oracle executes the resulting SQL. |
| 12 | + |
| 13 | +This means a feature such as title search belongs in the frontend query: add a search input and conditionally add a `where()` clause to the existing notes relation. Oracle's operators and built-in functions remain available with TypeScript types, and the filter is pushed down to Oracle. The client can author a new database query without adding a server endpoint or changing the authority boundary. |
| 14 | + |
| 15 | +Mutations follow the same graph. The user capability exposes note creation and supplies `this.id` as the new note's `user_id`. Once the frontend reaches one note through the user's relation, that note grants the ability to update or delete itself. |
| 16 | + |
| 17 | +Three properties of this model are particularly useful for agent-authored applications: |
| 18 | + |
| 19 | +1. Clients retain much of SQL's compositional power within the boundaries they have been given. |
| 20 | +2. Reads and mutations follow the same authority graph instead of reproducing it across CRUD endpoints and a separate policy layer. |
| 21 | +3. The main review surface is one file describing the data, relationships, allowed queries, and mutations—and that file is also the API. |
| 22 | + |
| 23 | +That is the durable core: the application and its authority model remain separate from the many clients or agent-authored interfaces that may use it. |
6 | 24 |
|
7 | 25 | ## Local development |
8 | 26 |
|
@@ -42,7 +60,7 @@ examples/oracle-notes/deploy.sh |
42 | 60 |
|
43 | 61 | `NOTES_DOMAIN` is intentionally deployment configuration. After deployment, `flyctl certs show` prints the A/AAAA or CNAME records to add at the domain's current DNS provider; Fly provisions and renews TLS. |
44 | 62 |
|
45 | | -The Oracle Machine remains running because database cold starts are expensive. The Node Machine may stop while idle and automatically starts on the next HTTP request. |
| 63 | +The Oracle Machine remains running because database cold starts are expensive. The Node Machine also keeps one instance running so the demo does not pay an application cold-start penalty. |
46 | 64 |
|
47 | 65 | ### Useful commands |
48 | 66 |
|
|
0 commit comments