> For the complete documentation index, see [llms.txt](https://seekspeed.gitbook.io/seekspeed-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://seekspeed.gitbook.io/seekspeed-docs/architecture/persistence.md).

# Persistence Layer

The persistence layer is hybrid: an in-memory workspace cache backed by debounced background upserts to Postgres. This keeps the UI instant while still making every entity durable and shareable.

## Read path

```
component  →  useWorkspace()  →  in-memory snapshot  (fast)
                       │
                       └──→ Postgres on cold start / explicit refresh
```

## Write path

```
component  →  storage.upsertAgent(a)
              │
              ├─→ optimistic merge into in-memory workspace
              └─→ schedule debounced upsert (250ms) to Postgres
```

`src/lib/storage.ts` exposes async CRUD helpers per entity (`upsertConnector`, `deleteAgent`, `appendRunResult`, `setRecommendationStatus`, etc.). Each writes through to its own table — there is no monolithic JSONB blob.

## Why no JSONB blob

Earlier prototypes stored the whole workspace as a single `data jsonb` column. That broke as soon as we wanted:

* A shareable single-report URL without exposing other rows.
* Server-side filtering for the command palette.
* RLS policies that distinguish read access per entity type.

Splitting into relational tables made all three trivial.

## Auth

We use Supabase Auth with three flows enabled:

* Email + password
* Google OAuth
* **Solana wallet** — see [Solana Wallet Auth](/seekspeed-docs/security/solana.md)

Every server function that mutates a workspace runs behind `requireSupabaseAuth` middleware, which attaches a per-request `supabase` client bound to the user's JWT. RLS then enforces row-level access at the database layer.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://seekspeed.gitbook.io/seekspeed-docs/architecture/persistence.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
