# Migrations and types

Keep the SQL that changes your schema as **versioned files**, and you can apply the same changes to another project (staging, then production)
in the same order. Changes made with `run_sql` leave no record.

```
list_migrations             version, name and time of each applied migration (oldest first)
apply_migrations            runs only the ones not yet applied, in version order, and records them
remove_migration_record     removes one record (what it made stays)
dump_schema                 the current schema as SQL that builds it again
generate_typescript_types   the Database type for supabase-js
```

## How they are applied

- One migration is **one transaction**. If it fails, that migration alone is rolled back whole and applying stops.
  The ones before it stay applied, and the ones after it are not run.
- Versions are numbers (usually `YYYYMMDDHHMMSS`) and run in numeric order. Versions already recorded are skipped.
- A new version **earlier** than the last applied one is refused. For a branch merged late, use `include_all: true`.
- A file whose content changed after it was recorded is not run again; it is reported as `drifted`. To fix something, write a new migration.
- It runs with the same rights as `run_sql` (a write token; owners, admins and developers), as the project's service_role.
  Creating a table turns RLS on, the same as there. One migration cannot take longer than 60 seconds.
- The data schema is first on the search_path, so a bare name such as `create table notes (...)` is enough.

## Where the record is kept

In the project's `oneend_migrations` table. The owner can read it with SQL; it has RLS on and no rules, so the publishable key cannot see it.
It plays the same part as `supabase_migrations.schema_migrations`.

## The schema as a file, the types as code

`dump_schema` gives types, sequences, tables and constraints, foreign keys, indexes, functions, views, triggers, RLS and rules as SQL.
When you start managing an existing project with migrations, save this as the first migration
and record it only, with `record_only: true` in `apply_migrations`. Running it would clash with the tables that already exist.

`generate_typescript_types` gives the same shape as `supabase gen types typescript` (Row/Insert/Update/Relationships under Tables,
Views, Args/Returns under Functions, Enums, CompositeTypes). The schema name is `public`.

## The same over HTTP

```
GET    /projects/<ref>/migrations
POST   /projects/<ref>/migrations          {migrations: [{version, name, sql}], include_all, record_only, dry_run}
DELETE /projects/<ref>/migrations/<version>
GET    /projects/<ref>/schema              {sql, objects}
GET    /projects/<ref>/types/typescript?schema=public   {types}
```

---

https://end.blackall.ai/docs/migrations?lang=en
