create-smoodly-app 0.0.26 → 0.0.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/templates/blank/package.json +1 -1
- package/templates/blank/supabase/migrations/20260926140000_smoodly_v3.sql +38 -0
- package/templates/blank/supabase/migrations/20260926150000_smoodly_v4.sql +41 -0
- package/templates/blank/supabase/migrations/{20260926130100_smoodly_views.sql → 20260926150100_smoodly_views.sql} +1 -1
- package/templates/blank-intl/package.json +1 -1
- package/templates/blank-intl/supabase/migrations/20260926140000_smoodly_v3.sql +38 -0
- package/templates/blank-intl/supabase/migrations/20260926150000_smoodly_v4.sql +41 -0
- package/templates/blank-intl/supabase/migrations/{20260926130100_smoodly_views.sql → 20260926150100_smoodly_views.sql} +1 -1
- package/templates/lorem/package.json +1 -1
- package/templates/lorem/supabase/migrations/20260926140000_smoodly_v3.sql +38 -0
- package/templates/lorem/supabase/migrations/20260926150000_smoodly_v4.sql +41 -0
- package/templates/lorem/supabase/migrations/{20260926130100_smoodly_views.sql → 20260926150100_smoodly_views.sql} +1 -1
- package/templates/lorem-intl/package.json +1 -1
- package/templates/lorem-intl/supabase/migrations/20260926140000_smoodly_v3.sql +38 -0
- package/templates/lorem-intl/supabase/migrations/20260926150000_smoodly_v4.sql +41 -0
- package/templates/lorem-intl/supabase/migrations/{20260926130100_smoodly_views.sql → 20260926150100_smoodly_views.sql} +1 -1
package/package.json
CHANGED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
-- Smoodly core schema, version 3 (docs/superpowers/specs/2026-09-26-security-pass-design.md).
|
|
2
|
+
-- Shipped in the smoodly package; `npx smoodly migrate` copies it into supabase/migrations/.
|
|
3
|
+
-- Never edit a published file: the next change is the next file.
|
|
4
|
+
-- The delta over version 2: the presence channel admits a signed-in
|
|
5
|
+
-- member of the topic's space (a definer lookup in members by the session
|
|
6
|
+
-- token's user), the five unpinned functions get a search_path, and the
|
|
7
|
+
-- three mutation RPCs are no longer executable by anon or public.
|
|
8
|
+
|
|
9
|
+
set client_min_messages = warning;
|
|
10
|
+
|
|
11
|
+
create or replace function "smoodly_presence_member"() returns boolean
|
|
12
|
+
language sql stable security definer set search_path = public as $$
|
|
13
|
+
select exists (select 1 from "members" m
|
|
14
|
+
where m."user_id" = auth.uid()
|
|
15
|
+
and realtime.topic() = 'space:' || m."space_id"::text);
|
|
16
|
+
$$;
|
|
17
|
+
|
|
18
|
+
drop policy if exists "smoodly_presence_read" on "realtime"."messages";
|
|
19
|
+
create policy "smoodly_presence_read" on "realtime"."messages" for select
|
|
20
|
+
using ((select public."smoodly_presence_member"()));
|
|
21
|
+
|
|
22
|
+
drop policy if exists "smoodly_presence_write" on "realtime"."messages";
|
|
23
|
+
create policy "smoodly_presence_write" on "realtime"."messages" for insert
|
|
24
|
+
with check ((select public."smoodly_presence_member"()));
|
|
25
|
+
|
|
26
|
+
alter function "smoodly_current_space"() set search_path = '';
|
|
27
|
+
alter function "smoodly_key_kind"() set search_path = '';
|
|
28
|
+
alter function "smoodly_set_space"() set search_path = '';
|
|
29
|
+
alter function "smoodly_reorder"(text, uuid[]) set search_path = public;
|
|
30
|
+
alter function "smoodly_reorder_pages"(uuid[]) set search_path = public;
|
|
31
|
+
alter function "smoodly_rewrite_paths"(jsonb, jsonb) set search_path = public;
|
|
32
|
+
|
|
33
|
+
revoke execute on function "smoodly_reorder"(text, uuid[]) from public, anon;
|
|
34
|
+
revoke execute on function "smoodly_reorder_pages"(uuid[]) from public, anon;
|
|
35
|
+
revoke execute on function "smoodly_rewrite_paths"(jsonb, jsonb) from public, anon;
|
|
36
|
+
|
|
37
|
+
insert into "smoodly_meta" ("key", "value") values ('schema_version', '3')
|
|
38
|
+
on conflict ("key") do update set "value" = excluded."value";
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
-- Smoodly core schema, version 4 (docs/superpowers/specs/2026-09-26-redirects-design.md).
|
|
2
|
+
-- Shipped in the smoodly package; `npx smoodly migrate` copies it into supabase/migrations/.
|
|
3
|
+
-- Never edit a published file: the next change is the next file.
|
|
4
|
+
-- The delta over version 3: a `redirect` flag on the paths index — a row
|
|
5
|
+
-- with it set is an old address of its target — and the rewrite function
|
|
6
|
+
-- keeps the published old rows as redirects when a target names their
|
|
7
|
+
-- locales. The read policy is unchanged: a redirect row is visible when
|
|
8
|
+
-- its target is published in that locale.
|
|
9
|
+
|
|
10
|
+
set client_min_messages = warning;
|
|
11
|
+
|
|
12
|
+
alter table "paths" add column if not exists "redirect" boolean not null default false;
|
|
13
|
+
|
|
14
|
+
create or replace function "smoodly_rewrite_paths"(p_targets jsonb, p_rows jsonb) returns void language sql set search_path = public as $$
|
|
15
|
+
delete from "paths" p
|
|
16
|
+
using jsonb_to_recordset(p_rows) as r(locale text, path text, kind text, id uuid)
|
|
17
|
+
where p."redirect" and p."locale" = r.locale and p."path" = r.path
|
|
18
|
+
and p."space_id" = "smoodly_current_space"();
|
|
19
|
+
update "paths" p set "redirect" = true
|
|
20
|
+
from jsonb_to_recordset(p_targets) as t(kind text, id uuid, redirect_locales text[])
|
|
21
|
+
where not p."redirect" and p."kind" = t.kind and p."target_id" = t.id
|
|
22
|
+
and p."locale" = any (coalesce(t.redirect_locales, '{}'::text[]))
|
|
23
|
+
and not exists (select 1 from jsonb_to_recordset(p_rows) as r(locale text, path text, kind text, id uuid)
|
|
24
|
+
where r.locale = p."locale" and r.path = p."path")
|
|
25
|
+
and p."space_id" = "smoodly_current_space"();
|
|
26
|
+
delete from "paths" p
|
|
27
|
+
using jsonb_to_recordset(p_targets) as t(kind text, id uuid, redirect_locales text[])
|
|
28
|
+
where p."kind" = t.kind and p."target_id" = t.id
|
|
29
|
+
and (not p."redirect" or not exists (select 1 from jsonb_to_recordset(p_rows) as r(locale text, path text, kind text, id uuid)
|
|
30
|
+
where r.kind = p."kind" and r.id = p."target_id" and r.locale = p."locale"))
|
|
31
|
+
and p."space_id" = "smoodly_current_space"();
|
|
32
|
+
insert into "paths" ("locale", "path", "kind", "target_id")
|
|
33
|
+
select r.locale, r.path, r.kind, r.id
|
|
34
|
+
from jsonb_to_recordset(p_rows) as r(locale text, path text, kind text, id uuid);
|
|
35
|
+
$$;
|
|
36
|
+
|
|
37
|
+
alter function "smoodly_rewrite_paths"(jsonb, jsonb) set search_path = public;
|
|
38
|
+
revoke execute on function "smoodly_rewrite_paths"(jsonb, jsonb) from public, anon;
|
|
39
|
+
|
|
40
|
+
insert into "smoodly_meta" ("key", "value") values ('schema_version', '4')
|
|
41
|
+
on conflict ("key") do update set "value" = excluded."value";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
-- Smoodly: read views and order indexes for this app's collections, written by `npx smoodly migrate`
|
|
2
|
-
-- (2026-09-
|
|
2
|
+
-- (2026-09-26T15:01:00.000Z). One block per collection; the marker's hash is the block's SQL, compared on the next run.
|
|
3
3
|
-- Never edit a written file: change the collection and run migrate again.
|
|
4
4
|
|
|
5
5
|
-- smoodly:collection posts sha256:2e648b887b8e7146
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
-- Smoodly core schema, version 3 (docs/superpowers/specs/2026-09-26-security-pass-design.md).
|
|
2
|
+
-- Shipped in the smoodly package; `npx smoodly migrate` copies it into supabase/migrations/.
|
|
3
|
+
-- Never edit a published file: the next change is the next file.
|
|
4
|
+
-- The delta over version 2: the presence channel admits a signed-in
|
|
5
|
+
-- member of the topic's space (a definer lookup in members by the session
|
|
6
|
+
-- token's user), the five unpinned functions get a search_path, and the
|
|
7
|
+
-- three mutation RPCs are no longer executable by anon or public.
|
|
8
|
+
|
|
9
|
+
set client_min_messages = warning;
|
|
10
|
+
|
|
11
|
+
create or replace function "smoodly_presence_member"() returns boolean
|
|
12
|
+
language sql stable security definer set search_path = public as $$
|
|
13
|
+
select exists (select 1 from "members" m
|
|
14
|
+
where m."user_id" = auth.uid()
|
|
15
|
+
and realtime.topic() = 'space:' || m."space_id"::text);
|
|
16
|
+
$$;
|
|
17
|
+
|
|
18
|
+
drop policy if exists "smoodly_presence_read" on "realtime"."messages";
|
|
19
|
+
create policy "smoodly_presence_read" on "realtime"."messages" for select
|
|
20
|
+
using ((select public."smoodly_presence_member"()));
|
|
21
|
+
|
|
22
|
+
drop policy if exists "smoodly_presence_write" on "realtime"."messages";
|
|
23
|
+
create policy "smoodly_presence_write" on "realtime"."messages" for insert
|
|
24
|
+
with check ((select public."smoodly_presence_member"()));
|
|
25
|
+
|
|
26
|
+
alter function "smoodly_current_space"() set search_path = '';
|
|
27
|
+
alter function "smoodly_key_kind"() set search_path = '';
|
|
28
|
+
alter function "smoodly_set_space"() set search_path = '';
|
|
29
|
+
alter function "smoodly_reorder"(text, uuid[]) set search_path = public;
|
|
30
|
+
alter function "smoodly_reorder_pages"(uuid[]) set search_path = public;
|
|
31
|
+
alter function "smoodly_rewrite_paths"(jsonb, jsonb) set search_path = public;
|
|
32
|
+
|
|
33
|
+
revoke execute on function "smoodly_reorder"(text, uuid[]) from public, anon;
|
|
34
|
+
revoke execute on function "smoodly_reorder_pages"(uuid[]) from public, anon;
|
|
35
|
+
revoke execute on function "smoodly_rewrite_paths"(jsonb, jsonb) from public, anon;
|
|
36
|
+
|
|
37
|
+
insert into "smoodly_meta" ("key", "value") values ('schema_version', '3')
|
|
38
|
+
on conflict ("key") do update set "value" = excluded."value";
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
-- Smoodly core schema, version 4 (docs/superpowers/specs/2026-09-26-redirects-design.md).
|
|
2
|
+
-- Shipped in the smoodly package; `npx smoodly migrate` copies it into supabase/migrations/.
|
|
3
|
+
-- Never edit a published file: the next change is the next file.
|
|
4
|
+
-- The delta over version 3: a `redirect` flag on the paths index — a row
|
|
5
|
+
-- with it set is an old address of its target — and the rewrite function
|
|
6
|
+
-- keeps the published old rows as redirects when a target names their
|
|
7
|
+
-- locales. The read policy is unchanged: a redirect row is visible when
|
|
8
|
+
-- its target is published in that locale.
|
|
9
|
+
|
|
10
|
+
set client_min_messages = warning;
|
|
11
|
+
|
|
12
|
+
alter table "paths" add column if not exists "redirect" boolean not null default false;
|
|
13
|
+
|
|
14
|
+
create or replace function "smoodly_rewrite_paths"(p_targets jsonb, p_rows jsonb) returns void language sql set search_path = public as $$
|
|
15
|
+
delete from "paths" p
|
|
16
|
+
using jsonb_to_recordset(p_rows) as r(locale text, path text, kind text, id uuid)
|
|
17
|
+
where p."redirect" and p."locale" = r.locale and p."path" = r.path
|
|
18
|
+
and p."space_id" = "smoodly_current_space"();
|
|
19
|
+
update "paths" p set "redirect" = true
|
|
20
|
+
from jsonb_to_recordset(p_targets) as t(kind text, id uuid, redirect_locales text[])
|
|
21
|
+
where not p."redirect" and p."kind" = t.kind and p."target_id" = t.id
|
|
22
|
+
and p."locale" = any (coalesce(t.redirect_locales, '{}'::text[]))
|
|
23
|
+
and not exists (select 1 from jsonb_to_recordset(p_rows) as r(locale text, path text, kind text, id uuid)
|
|
24
|
+
where r.locale = p."locale" and r.path = p."path")
|
|
25
|
+
and p."space_id" = "smoodly_current_space"();
|
|
26
|
+
delete from "paths" p
|
|
27
|
+
using jsonb_to_recordset(p_targets) as t(kind text, id uuid, redirect_locales text[])
|
|
28
|
+
where p."kind" = t.kind and p."target_id" = t.id
|
|
29
|
+
and (not p."redirect" or not exists (select 1 from jsonb_to_recordset(p_rows) as r(locale text, path text, kind text, id uuid)
|
|
30
|
+
where r.kind = p."kind" and r.id = p."target_id" and r.locale = p."locale"))
|
|
31
|
+
and p."space_id" = "smoodly_current_space"();
|
|
32
|
+
insert into "paths" ("locale", "path", "kind", "target_id")
|
|
33
|
+
select r.locale, r.path, r.kind, r.id
|
|
34
|
+
from jsonb_to_recordset(p_rows) as r(locale text, path text, kind text, id uuid);
|
|
35
|
+
$$;
|
|
36
|
+
|
|
37
|
+
alter function "smoodly_rewrite_paths"(jsonb, jsonb) set search_path = public;
|
|
38
|
+
revoke execute on function "smoodly_rewrite_paths"(jsonb, jsonb) from public, anon;
|
|
39
|
+
|
|
40
|
+
insert into "smoodly_meta" ("key", "value") values ('schema_version', '4')
|
|
41
|
+
on conflict ("key") do update set "value" = excluded."value";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
-- Smoodly: read views and order indexes for this app's collections, written by `npx smoodly migrate`
|
|
2
|
-
-- (2026-09-
|
|
2
|
+
-- (2026-09-26T15:01:00.000Z). One block per collection; the marker's hash is the block's SQL, compared on the next run.
|
|
3
3
|
-- Never edit a written file: change the collection and run migrate again.
|
|
4
4
|
|
|
5
5
|
-- smoodly:collection posts sha256:2e648b887b8e7146
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
-- Smoodly core schema, version 3 (docs/superpowers/specs/2026-09-26-security-pass-design.md).
|
|
2
|
+
-- Shipped in the smoodly package; `npx smoodly migrate` copies it into supabase/migrations/.
|
|
3
|
+
-- Never edit a published file: the next change is the next file.
|
|
4
|
+
-- The delta over version 2: the presence channel admits a signed-in
|
|
5
|
+
-- member of the topic's space (a definer lookup in members by the session
|
|
6
|
+
-- token's user), the five unpinned functions get a search_path, and the
|
|
7
|
+
-- three mutation RPCs are no longer executable by anon or public.
|
|
8
|
+
|
|
9
|
+
set client_min_messages = warning;
|
|
10
|
+
|
|
11
|
+
create or replace function "smoodly_presence_member"() returns boolean
|
|
12
|
+
language sql stable security definer set search_path = public as $$
|
|
13
|
+
select exists (select 1 from "members" m
|
|
14
|
+
where m."user_id" = auth.uid()
|
|
15
|
+
and realtime.topic() = 'space:' || m."space_id"::text);
|
|
16
|
+
$$;
|
|
17
|
+
|
|
18
|
+
drop policy if exists "smoodly_presence_read" on "realtime"."messages";
|
|
19
|
+
create policy "smoodly_presence_read" on "realtime"."messages" for select
|
|
20
|
+
using ((select public."smoodly_presence_member"()));
|
|
21
|
+
|
|
22
|
+
drop policy if exists "smoodly_presence_write" on "realtime"."messages";
|
|
23
|
+
create policy "smoodly_presence_write" on "realtime"."messages" for insert
|
|
24
|
+
with check ((select public."smoodly_presence_member"()));
|
|
25
|
+
|
|
26
|
+
alter function "smoodly_current_space"() set search_path = '';
|
|
27
|
+
alter function "smoodly_key_kind"() set search_path = '';
|
|
28
|
+
alter function "smoodly_set_space"() set search_path = '';
|
|
29
|
+
alter function "smoodly_reorder"(text, uuid[]) set search_path = public;
|
|
30
|
+
alter function "smoodly_reorder_pages"(uuid[]) set search_path = public;
|
|
31
|
+
alter function "smoodly_rewrite_paths"(jsonb, jsonb) set search_path = public;
|
|
32
|
+
|
|
33
|
+
revoke execute on function "smoodly_reorder"(text, uuid[]) from public, anon;
|
|
34
|
+
revoke execute on function "smoodly_reorder_pages"(uuid[]) from public, anon;
|
|
35
|
+
revoke execute on function "smoodly_rewrite_paths"(jsonb, jsonb) from public, anon;
|
|
36
|
+
|
|
37
|
+
insert into "smoodly_meta" ("key", "value") values ('schema_version', '3')
|
|
38
|
+
on conflict ("key") do update set "value" = excluded."value";
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
-- Smoodly core schema, version 4 (docs/superpowers/specs/2026-09-26-redirects-design.md).
|
|
2
|
+
-- Shipped in the smoodly package; `npx smoodly migrate` copies it into supabase/migrations/.
|
|
3
|
+
-- Never edit a published file: the next change is the next file.
|
|
4
|
+
-- The delta over version 3: a `redirect` flag on the paths index — a row
|
|
5
|
+
-- with it set is an old address of its target — and the rewrite function
|
|
6
|
+
-- keeps the published old rows as redirects when a target names their
|
|
7
|
+
-- locales. The read policy is unchanged: a redirect row is visible when
|
|
8
|
+
-- its target is published in that locale.
|
|
9
|
+
|
|
10
|
+
set client_min_messages = warning;
|
|
11
|
+
|
|
12
|
+
alter table "paths" add column if not exists "redirect" boolean not null default false;
|
|
13
|
+
|
|
14
|
+
create or replace function "smoodly_rewrite_paths"(p_targets jsonb, p_rows jsonb) returns void language sql set search_path = public as $$
|
|
15
|
+
delete from "paths" p
|
|
16
|
+
using jsonb_to_recordset(p_rows) as r(locale text, path text, kind text, id uuid)
|
|
17
|
+
where p."redirect" and p."locale" = r.locale and p."path" = r.path
|
|
18
|
+
and p."space_id" = "smoodly_current_space"();
|
|
19
|
+
update "paths" p set "redirect" = true
|
|
20
|
+
from jsonb_to_recordset(p_targets) as t(kind text, id uuid, redirect_locales text[])
|
|
21
|
+
where not p."redirect" and p."kind" = t.kind and p."target_id" = t.id
|
|
22
|
+
and p."locale" = any (coalesce(t.redirect_locales, '{}'::text[]))
|
|
23
|
+
and not exists (select 1 from jsonb_to_recordset(p_rows) as r(locale text, path text, kind text, id uuid)
|
|
24
|
+
where r.locale = p."locale" and r.path = p."path")
|
|
25
|
+
and p."space_id" = "smoodly_current_space"();
|
|
26
|
+
delete from "paths" p
|
|
27
|
+
using jsonb_to_recordset(p_targets) as t(kind text, id uuid, redirect_locales text[])
|
|
28
|
+
where p."kind" = t.kind and p."target_id" = t.id
|
|
29
|
+
and (not p."redirect" or not exists (select 1 from jsonb_to_recordset(p_rows) as r(locale text, path text, kind text, id uuid)
|
|
30
|
+
where r.kind = p."kind" and r.id = p."target_id" and r.locale = p."locale"))
|
|
31
|
+
and p."space_id" = "smoodly_current_space"();
|
|
32
|
+
insert into "paths" ("locale", "path", "kind", "target_id")
|
|
33
|
+
select r.locale, r.path, r.kind, r.id
|
|
34
|
+
from jsonb_to_recordset(p_rows) as r(locale text, path text, kind text, id uuid);
|
|
35
|
+
$$;
|
|
36
|
+
|
|
37
|
+
alter function "smoodly_rewrite_paths"(jsonb, jsonb) set search_path = public;
|
|
38
|
+
revoke execute on function "smoodly_rewrite_paths"(jsonb, jsonb) from public, anon;
|
|
39
|
+
|
|
40
|
+
insert into "smoodly_meta" ("key", "value") values ('schema_version', '4')
|
|
41
|
+
on conflict ("key") do update set "value" = excluded."value";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
-- Smoodly: read views and order indexes for this app's collections, written by `npx smoodly migrate`
|
|
2
|
-
-- (2026-09-
|
|
2
|
+
-- (2026-09-26T15:01:00.000Z). One block per collection; the marker's hash is the block's SQL, compared on the next run.
|
|
3
3
|
-- Never edit a written file: change the collection and run migrate again.
|
|
4
4
|
|
|
5
5
|
-- smoodly:collection people sha256:929798ebb4fa2bb6
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
-- Smoodly core schema, version 3 (docs/superpowers/specs/2026-09-26-security-pass-design.md).
|
|
2
|
+
-- Shipped in the smoodly package; `npx smoodly migrate` copies it into supabase/migrations/.
|
|
3
|
+
-- Never edit a published file: the next change is the next file.
|
|
4
|
+
-- The delta over version 2: the presence channel admits a signed-in
|
|
5
|
+
-- member of the topic's space (a definer lookup in members by the session
|
|
6
|
+
-- token's user), the five unpinned functions get a search_path, and the
|
|
7
|
+
-- three mutation RPCs are no longer executable by anon or public.
|
|
8
|
+
|
|
9
|
+
set client_min_messages = warning;
|
|
10
|
+
|
|
11
|
+
create or replace function "smoodly_presence_member"() returns boolean
|
|
12
|
+
language sql stable security definer set search_path = public as $$
|
|
13
|
+
select exists (select 1 from "members" m
|
|
14
|
+
where m."user_id" = auth.uid()
|
|
15
|
+
and realtime.topic() = 'space:' || m."space_id"::text);
|
|
16
|
+
$$;
|
|
17
|
+
|
|
18
|
+
drop policy if exists "smoodly_presence_read" on "realtime"."messages";
|
|
19
|
+
create policy "smoodly_presence_read" on "realtime"."messages" for select
|
|
20
|
+
using ((select public."smoodly_presence_member"()));
|
|
21
|
+
|
|
22
|
+
drop policy if exists "smoodly_presence_write" on "realtime"."messages";
|
|
23
|
+
create policy "smoodly_presence_write" on "realtime"."messages" for insert
|
|
24
|
+
with check ((select public."smoodly_presence_member"()));
|
|
25
|
+
|
|
26
|
+
alter function "smoodly_current_space"() set search_path = '';
|
|
27
|
+
alter function "smoodly_key_kind"() set search_path = '';
|
|
28
|
+
alter function "smoodly_set_space"() set search_path = '';
|
|
29
|
+
alter function "smoodly_reorder"(text, uuid[]) set search_path = public;
|
|
30
|
+
alter function "smoodly_reorder_pages"(uuid[]) set search_path = public;
|
|
31
|
+
alter function "smoodly_rewrite_paths"(jsonb, jsonb) set search_path = public;
|
|
32
|
+
|
|
33
|
+
revoke execute on function "smoodly_reorder"(text, uuid[]) from public, anon;
|
|
34
|
+
revoke execute on function "smoodly_reorder_pages"(uuid[]) from public, anon;
|
|
35
|
+
revoke execute on function "smoodly_rewrite_paths"(jsonb, jsonb) from public, anon;
|
|
36
|
+
|
|
37
|
+
insert into "smoodly_meta" ("key", "value") values ('schema_version', '3')
|
|
38
|
+
on conflict ("key") do update set "value" = excluded."value";
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
-- Smoodly core schema, version 4 (docs/superpowers/specs/2026-09-26-redirects-design.md).
|
|
2
|
+
-- Shipped in the smoodly package; `npx smoodly migrate` copies it into supabase/migrations/.
|
|
3
|
+
-- Never edit a published file: the next change is the next file.
|
|
4
|
+
-- The delta over version 3: a `redirect` flag on the paths index — a row
|
|
5
|
+
-- with it set is an old address of its target — and the rewrite function
|
|
6
|
+
-- keeps the published old rows as redirects when a target names their
|
|
7
|
+
-- locales. The read policy is unchanged: a redirect row is visible when
|
|
8
|
+
-- its target is published in that locale.
|
|
9
|
+
|
|
10
|
+
set client_min_messages = warning;
|
|
11
|
+
|
|
12
|
+
alter table "paths" add column if not exists "redirect" boolean not null default false;
|
|
13
|
+
|
|
14
|
+
create or replace function "smoodly_rewrite_paths"(p_targets jsonb, p_rows jsonb) returns void language sql set search_path = public as $$
|
|
15
|
+
delete from "paths" p
|
|
16
|
+
using jsonb_to_recordset(p_rows) as r(locale text, path text, kind text, id uuid)
|
|
17
|
+
where p."redirect" and p."locale" = r.locale and p."path" = r.path
|
|
18
|
+
and p."space_id" = "smoodly_current_space"();
|
|
19
|
+
update "paths" p set "redirect" = true
|
|
20
|
+
from jsonb_to_recordset(p_targets) as t(kind text, id uuid, redirect_locales text[])
|
|
21
|
+
where not p."redirect" and p."kind" = t.kind and p."target_id" = t.id
|
|
22
|
+
and p."locale" = any (coalesce(t.redirect_locales, '{}'::text[]))
|
|
23
|
+
and not exists (select 1 from jsonb_to_recordset(p_rows) as r(locale text, path text, kind text, id uuid)
|
|
24
|
+
where r.locale = p."locale" and r.path = p."path")
|
|
25
|
+
and p."space_id" = "smoodly_current_space"();
|
|
26
|
+
delete from "paths" p
|
|
27
|
+
using jsonb_to_recordset(p_targets) as t(kind text, id uuid, redirect_locales text[])
|
|
28
|
+
where p."kind" = t.kind and p."target_id" = t.id
|
|
29
|
+
and (not p."redirect" or not exists (select 1 from jsonb_to_recordset(p_rows) as r(locale text, path text, kind text, id uuid)
|
|
30
|
+
where r.kind = p."kind" and r.id = p."target_id" and r.locale = p."locale"))
|
|
31
|
+
and p."space_id" = "smoodly_current_space"();
|
|
32
|
+
insert into "paths" ("locale", "path", "kind", "target_id")
|
|
33
|
+
select r.locale, r.path, r.kind, r.id
|
|
34
|
+
from jsonb_to_recordset(p_rows) as r(locale text, path text, kind text, id uuid);
|
|
35
|
+
$$;
|
|
36
|
+
|
|
37
|
+
alter function "smoodly_rewrite_paths"(jsonb, jsonb) set search_path = public;
|
|
38
|
+
revoke execute on function "smoodly_rewrite_paths"(jsonb, jsonb) from public, anon;
|
|
39
|
+
|
|
40
|
+
insert into "smoodly_meta" ("key", "value") values ('schema_version', '4')
|
|
41
|
+
on conflict ("key") do update set "value" = excluded."value";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
-- Smoodly: read views and order indexes for this app's collections, written by `npx smoodly migrate`
|
|
2
|
-
-- (2026-09-
|
|
2
|
+
-- (2026-09-26T15:01:00.000Z). One block per collection; the marker's hash is the block's SQL, compared on the next run.
|
|
3
3
|
-- Never edit a written file: change the collection and run migrate again.
|
|
4
4
|
|
|
5
5
|
-- smoodly:collection people sha256:929798ebb4fa2bb6
|