create-smoodly-app 0.0.6 → 0.0.8
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 +2 -2
- package/templates/next/app/layout.tsx +18 -2
- package/templates/next/components/pages/Home.tsx +2 -1
- package/templates/next/components/pages/Page.tsx +2 -1
- package/templates/next/components/sections/Footer.tsx +33 -0
- package/templates/next/components/sections/Testimonials.tsx +30 -0
- package/templates/next/package.json +1 -1
- package/templates/next/smoodly/collections.ts +10 -3
- package/templates/next/smoodly/config.ts +3 -1
- package/templates/next/smoodly/sections.ts +3 -1
- package/templates/next/smoodly/server.ts +4 -3
- package/templates/next/smoodly/shared.ts +22 -0
- package/templates/next/supabase/migrations/00000000000000_smoodly.sql +143 -101
- package/templates/next-intl/app/[locale]/layout.tsx +12 -1
- package/templates/next-intl/components/pages/Home.tsx +2 -1
- package/templates/next-intl/components/pages/Page.tsx +2 -1
- package/templates/next-intl/components/sections/Footer.tsx +33 -0
- package/templates/next-intl/components/sections/Testimonials.tsx +30 -0
- package/templates/next-intl/package.json +1 -1
- package/templates/next-intl/smoodly/collections.ts +10 -3
- package/templates/next-intl/smoodly/config.ts +3 -1
- package/templates/next-intl/smoodly/sections.ts +3 -1
- package/templates/next-intl/smoodly/server.ts +4 -3
- package/templates/next-intl/smoodly/shared.ts +22 -0
- package/templates/next-intl/supabase/migrations/00000000000000_smoodly.sql +143 -101
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// Shared content (spec 2026-09-07): code-declared singletons stored as
|
|
2
|
+
// entries. `footer` is visual — the layout renders it; `contact` is an
|
|
3
|
+
// object the layout reads; `testimonials` is visual and placed on pages.
|
|
4
|
+
import { f, smoodly } from "smoodly";
|
|
5
|
+
import { Footer } from "@/components/sections/Footer";
|
|
6
|
+
import { Testimonials } from "@/components/sections/Testimonials";
|
|
7
|
+
|
|
8
|
+
export const footer = smoodly.shared({ name: "footer", title: "Footer", section: Footer, versions: true });
|
|
9
|
+
|
|
10
|
+
export const contact = smoodly.shared({
|
|
11
|
+
name: "contact",
|
|
12
|
+
title: "Contact details",
|
|
13
|
+
fields: {
|
|
14
|
+
email: f.text(),
|
|
15
|
+
phone: f.text().optional(),
|
|
16
|
+
address: f.text().localized(),
|
|
17
|
+
},
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
export const testimonials = smoodly.shared({ name: "testimonials", title: "Testimonials", section: Testimonials });
|
|
21
|
+
|
|
22
|
+
export const shared = [footer, contact, testimonials];
|
|
@@ -12,28 +12,34 @@ create table if not exists "pages" (
|
|
|
12
12
|
"id" uuid primary key default gen_random_uuid(),
|
|
13
13
|
"space_id" uuid not null default '00000000-0000-0000-0000-000000000000',
|
|
14
14
|
"parent_id" uuid references "pages" ("id") on delete restrict,
|
|
15
|
-
"slug" text not null,
|
|
16
|
-
"title" text not null,
|
|
17
|
-
"i18n" jsonb,
|
|
18
15
|
"template" text,
|
|
19
|
-
"status" text not null default 'draft',
|
|
20
16
|
"sort" numeric,
|
|
21
|
-
"locales" text[],
|
|
22
|
-
"draft_version_id" uuid,
|
|
23
|
-
"published_version_id" uuid,
|
|
24
17
|
"created_at" timestamptz not null default now(),
|
|
25
18
|
"updated_at" timestamptz not null default now()
|
|
26
19
|
);
|
|
27
20
|
|
|
28
|
-
-- The tree is the URL (spec 2026-09-05 §1): a node stores its
|
|
29
|
-
--
|
|
30
|
-
--
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
21
|
+
-- The tree is the URL (spec 2026-09-05 §1): a node stores its parent and
|
|
22
|
+
-- its position; template null = folder. Everything a locale owns — the
|
|
23
|
+
-- node's own segment, title, publish state and version pointers — lives
|
|
24
|
+
-- in page_locales, one row per locale the page exists in (spec 2026-09-06
|
|
25
|
+
-- §2). There is no sibling-slug index: URL uniqueness per locale is the
|
|
26
|
+
-- primary key of "paths", which the stores write inside the same operation.
|
|
34
27
|
create index if not exists "pages_parent_idx"
|
|
35
28
|
on "pages" ("space_id", "parent_id", "sort");
|
|
36
29
|
|
|
30
|
+
create table if not exists "page_locales" (
|
|
31
|
+
"space_id" uuid not null default '00000000-0000-0000-0000-000000000000',
|
|
32
|
+
"page_id" uuid not null references "pages" ("id") on delete cascade,
|
|
33
|
+
"locale" text not null,
|
|
34
|
+
"slug" text not null,
|
|
35
|
+
"title" text not null,
|
|
36
|
+
"status" text not null default 'draft',
|
|
37
|
+
"draft_version_id" uuid,
|
|
38
|
+
"published_version_id" uuid,
|
|
39
|
+
"updated_at" timestamptz not null default now(),
|
|
40
|
+
primary key ("page_id", "locale")
|
|
41
|
+
);
|
|
42
|
+
|
|
37
43
|
-- Sibling reorder for pages: same shape as smoodly_reorder for entries.
|
|
38
44
|
create or replace function "smoodly_reorder_pages"(p_ids uuid[]) returns void language sql as $$
|
|
39
45
|
update "pages" pg set "sort" = u.ord
|
|
@@ -42,30 +48,20 @@ create or replace function "smoodly_reorder_pages"(p_ids uuid[]) returns void la
|
|
|
42
48
|
and pg."space_id" = "smoodly_current_space"();
|
|
43
49
|
$$;
|
|
44
50
|
|
|
51
|
+
-- A version belongs to ONE locale of one page: each locale has its own
|
|
52
|
+
-- draft, its own publish and its own history.
|
|
45
53
|
create table if not exists "page_versions" (
|
|
46
54
|
"id" uuid primary key default gen_random_uuid(),
|
|
47
55
|
"space_id" uuid not null default '00000000-0000-0000-0000-000000000000',
|
|
48
56
|
"page_id" uuid not null references "pages" ("id") on delete cascade,
|
|
57
|
+
"locale" text not null,
|
|
49
58
|
"tree" jsonb not null,
|
|
50
59
|
"created_by" text,
|
|
51
60
|
"created_at" timestamptz not null default now()
|
|
52
61
|
);
|
|
53
62
|
|
|
54
|
-
create
|
|
55
|
-
"
|
|
56
|
-
"space_id" uuid not null default '00000000-0000-0000-0000-000000000000',
|
|
57
|
-
"title" text not null,
|
|
58
|
-
"fragment" jsonb not null,
|
|
59
|
-
"created_at" timestamptz not null default now()
|
|
60
|
-
);
|
|
61
|
-
|
|
62
|
-
create table if not exists "global_sections" (
|
|
63
|
-
"id" uuid primary key default gen_random_uuid(),
|
|
64
|
-
"space_id" uuid not null default '00000000-0000-0000-0000-000000000000',
|
|
65
|
-
"type" text not null,
|
|
66
|
-
"content" jsonb not null,
|
|
67
|
-
"updated_at" timestamptz not null default now()
|
|
68
|
-
);
|
|
63
|
+
create index if not exists "page_versions_page_locale_idx"
|
|
64
|
+
on "page_versions" ("page_id", "locale", "created_at");
|
|
69
65
|
|
|
70
66
|
create table if not exists "entries" (
|
|
71
67
|
"id" uuid primary key default gen_random_uuid(),
|
|
@@ -73,40 +69,58 @@ create table if not exists "entries" (
|
|
|
73
69
|
"collection" text not null,
|
|
74
70
|
"parent_id" uuid references "entries" ("id") on delete restrict,
|
|
75
71
|
"fields" jsonb not null default '{}'::jsonb,
|
|
76
|
-
"i18n" jsonb,
|
|
77
|
-
"status" text not null default 'draft',
|
|
78
72
|
"sort" numeric,
|
|
79
|
-
"locales" text[],
|
|
80
73
|
"created_at" timestamptz not null default now(),
|
|
81
74
|
"updated_at" timestamptz not null default now()
|
|
82
75
|
);
|
|
83
76
|
|
|
84
|
-
--
|
|
85
|
-
--
|
|
86
|
-
--
|
|
87
|
-
--
|
|
88
|
-
--
|
|
89
|
-
--
|
|
90
|
-
--
|
|
91
|
-
--
|
|
92
|
-
-- a number, boolean or null slug would otherwise print as non-empty
|
|
93
|
-
-- text and claim the index; only a non-empty string slug claims a URL,
|
|
94
|
-
-- absent, null, empty or non-string slugs never conflict — the same
|
|
95
|
-
-- rule as slugOf in paths.ts. A flat collection (every entry a root)
|
|
96
|
-
-- therefore behaves exactly as per-collection uniqueness did.
|
|
97
|
-
create unique index if not exists "entries_sibling_slug_key"
|
|
98
|
-
on "entries" ("space_id", "collection", "parent_id", ("fields"->>'slug')) nulls not distinct
|
|
99
|
-
where (jsonb_typeof("fields"->'slug') = 'string' and "fields"->>'slug' <> '');
|
|
100
|
-
|
|
101
|
-
create index if not exists "entries_collection_status_idx"
|
|
102
|
-
on "entries" ("space_id", "collection", "status");
|
|
103
|
-
|
|
77
|
+
-- The node holds identity, tree position and the SHARED fields — every
|
|
78
|
+
-- field without .localized() (spec 2026-09-06 §7): a Person's photo is
|
|
79
|
+
-- the same in every language. Everything a locale owns — its segment,
|
|
80
|
+
-- publish state, the .localized() fields and the version pointers —
|
|
81
|
+
-- lives in entry_locales, one row per locale the entry exists in. There
|
|
82
|
+
-- is no sibling-slug index any more: URL uniqueness per locale is the
|
|
83
|
+
-- primary key of "paths", which the stores write inside the same
|
|
84
|
+
-- operation, and both adapters pre-check siblings per locale in code.
|
|
104
85
|
create index if not exists "entries_collection_sort_idx"
|
|
105
86
|
on "entries" ("space_id", "collection", "sort");
|
|
106
87
|
|
|
107
88
|
create index if not exists "entries_parent_idx"
|
|
108
89
|
on "entries" ("space_id", "collection", "parent_id");
|
|
109
90
|
|
|
91
|
+
create table if not exists "entry_locales" (
|
|
92
|
+
"space_id" uuid not null default '00000000-0000-0000-0000-000000000000',
|
|
93
|
+
"entry_id" uuid not null references "entries" ("id") on delete cascade,
|
|
94
|
+
"locale" text not null,
|
|
95
|
+
"slug" text,
|
|
96
|
+
"status" text not null default 'draft',
|
|
97
|
+
"fields" jsonb not null default '{}'::jsonb,
|
|
98
|
+
"draft_version_id" uuid,
|
|
99
|
+
"published_version_id" uuid,
|
|
100
|
+
"updated_at" timestamptz not null default now(),
|
|
101
|
+
primary key ("entry_id", "locale")
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
create index if not exists "entry_locales_status_idx"
|
|
105
|
+
on "entry_locales" ("space_id", "locale", "status");
|
|
106
|
+
|
|
107
|
+
-- A version belongs to ONE locale of one entry and stores the MERGED
|
|
108
|
+
-- fields (shared + localized + slug) as they were at that save, so
|
|
109
|
+
-- restoring an old Finnish version restores the shared fields too.
|
|
110
|
+
-- Rows exist only for collections registered with `versions: true`.
|
|
111
|
+
create table if not exists "entry_versions" (
|
|
112
|
+
"id" uuid primary key default gen_random_uuid(),
|
|
113
|
+
"space_id" uuid not null default '00000000-0000-0000-0000-000000000000',
|
|
114
|
+
"entry_id" uuid not null references "entries" ("id") on delete cascade,
|
|
115
|
+
"locale" text not null,
|
|
116
|
+
"fields" jsonb not null,
|
|
117
|
+
"created_by" text,
|
|
118
|
+
"created_at" timestamptz not null default now()
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
create index if not exists "entry_versions_entry_locale_idx"
|
|
122
|
+
on "entry_versions" ("entry_id", "locale", "created_at");
|
|
123
|
+
|
|
110
124
|
-- v1 reorder (DESIGN.md §3 Manual ordering): rewrite sort 1..N in ONE
|
|
111
125
|
-- statement. Deliberately does not touch updated_at — a drag must not
|
|
112
126
|
-- make the whole collection look freshly edited. Scoped to the current
|
|
@@ -172,10 +186,11 @@ $$;
|
|
|
172
186
|
-- (collectionSQL) run with security_invoker = true, so they are subject
|
|
173
187
|
-- to this same smoodly_read policy rather than their owner's privileges.
|
|
174
188
|
alter table "pages" enable row level security;
|
|
189
|
+
alter table "page_locales" enable row level security;
|
|
175
190
|
alter table "page_versions" enable row level security;
|
|
176
|
-
alter table "saved_sections" enable row level security;
|
|
177
|
-
alter table "global_sections" enable row level security;
|
|
178
191
|
alter table "entries" enable row level security;
|
|
192
|
+
alter table "entry_locales" enable row level security;
|
|
193
|
+
alter table "entry_versions" enable row level security;
|
|
179
194
|
alter table "refs" enable row level security;
|
|
180
195
|
alter table "paths" enable row level security;
|
|
181
196
|
|
|
@@ -272,11 +287,13 @@ begin
|
|
|
272
287
|
end;
|
|
273
288
|
$$;
|
|
274
289
|
|
|
290
|
+
create index if not exists "page_locales_space_idx" on "page_locales" ("space_id");
|
|
291
|
+
|
|
275
292
|
create index if not exists "page_versions_space_idx" on "page_versions" ("space_id");
|
|
276
293
|
|
|
277
|
-
create index if not exists "
|
|
294
|
+
create index if not exists "entry_locales_space_idx" on "entry_locales" ("space_id");
|
|
278
295
|
|
|
279
|
-
create index if not exists "
|
|
296
|
+
create index if not exists "entry_versions_space_idx" on "entry_versions" ("space_id");
|
|
280
297
|
|
|
281
298
|
create index if not exists "refs_space_idx" on "refs" ("space_id");
|
|
282
299
|
|
|
@@ -284,20 +301,24 @@ drop trigger if exists "smoodly_a_set_space" on "pages";
|
|
|
284
301
|
create trigger "smoodly_a_set_space" before insert on "pages"
|
|
285
302
|
for each row execute function "smoodly_set_space"();
|
|
286
303
|
|
|
304
|
+
drop trigger if exists "smoodly_a_set_space" on "page_locales";
|
|
305
|
+
create trigger "smoodly_a_set_space" before insert on "page_locales"
|
|
306
|
+
for each row execute function "smoodly_set_space"();
|
|
307
|
+
|
|
287
308
|
drop trigger if exists "smoodly_a_set_space" on "page_versions";
|
|
288
309
|
create trigger "smoodly_a_set_space" before insert on "page_versions"
|
|
289
310
|
for each row execute function "smoodly_set_space"();
|
|
290
311
|
|
|
291
|
-
drop trigger if exists "smoodly_a_set_space" on "
|
|
292
|
-
create trigger "smoodly_a_set_space" before insert on "
|
|
312
|
+
drop trigger if exists "smoodly_a_set_space" on "entries";
|
|
313
|
+
create trigger "smoodly_a_set_space" before insert on "entries"
|
|
293
314
|
for each row execute function "smoodly_set_space"();
|
|
294
315
|
|
|
295
|
-
drop trigger if exists "smoodly_a_set_space" on "
|
|
296
|
-
create trigger "smoodly_a_set_space" before insert on "
|
|
316
|
+
drop trigger if exists "smoodly_a_set_space" on "entry_locales";
|
|
317
|
+
create trigger "smoodly_a_set_space" before insert on "entry_locales"
|
|
297
318
|
for each row execute function "smoodly_set_space"();
|
|
298
319
|
|
|
299
|
-
drop trigger if exists "smoodly_a_set_space" on "
|
|
300
|
-
create trigger "smoodly_a_set_space" before insert on "
|
|
320
|
+
drop trigger if exists "smoodly_a_set_space" on "entry_versions";
|
|
321
|
+
create trigger "smoodly_a_set_space" before insert on "entry_versions"
|
|
301
322
|
for each row execute function "smoodly_set_space"();
|
|
302
323
|
|
|
303
324
|
drop trigger if exists "smoodly_a_set_space" on "refs";
|
|
@@ -316,20 +337,24 @@ drop trigger if exists "smoodly_b_row_cap" on "pages";
|
|
|
316
337
|
create trigger "smoodly_b_row_cap" before insert on "pages"
|
|
317
338
|
for each row execute function "smoodly_enforce_row_cap"();
|
|
318
339
|
|
|
340
|
+
drop trigger if exists "smoodly_b_row_cap" on "page_locales";
|
|
341
|
+
create trigger "smoodly_b_row_cap" before insert on "page_locales"
|
|
342
|
+
for each row execute function "smoodly_enforce_row_cap"();
|
|
343
|
+
|
|
319
344
|
drop trigger if exists "smoodly_b_row_cap" on "page_versions";
|
|
320
345
|
create trigger "smoodly_b_row_cap" before insert on "page_versions"
|
|
321
346
|
for each row execute function "smoodly_enforce_row_cap"();
|
|
322
347
|
|
|
323
|
-
drop trigger if exists "smoodly_b_row_cap" on "
|
|
324
|
-
create trigger "smoodly_b_row_cap" before insert on "
|
|
348
|
+
drop trigger if exists "smoodly_b_row_cap" on "entries";
|
|
349
|
+
create trigger "smoodly_b_row_cap" before insert on "entries"
|
|
325
350
|
for each row execute function "smoodly_enforce_row_cap"();
|
|
326
351
|
|
|
327
|
-
drop trigger if exists "smoodly_b_row_cap" on "
|
|
328
|
-
create trigger "smoodly_b_row_cap" before insert on "
|
|
352
|
+
drop trigger if exists "smoodly_b_row_cap" on "entry_locales";
|
|
353
|
+
create trigger "smoodly_b_row_cap" before insert on "entry_locales"
|
|
329
354
|
for each row execute function "smoodly_enforce_row_cap"();
|
|
330
355
|
|
|
331
|
-
drop trigger if exists "smoodly_b_row_cap" on "
|
|
332
|
-
create trigger "smoodly_b_row_cap" before insert on "
|
|
356
|
+
drop trigger if exists "smoodly_b_row_cap" on "entry_versions";
|
|
357
|
+
create trigger "smoodly_b_row_cap" before insert on "entry_versions"
|
|
333
358
|
for each row execute function "smoodly_enforce_row_cap"();
|
|
334
359
|
|
|
335
360
|
drop trigger if exists "smoodly_b_row_cap" on "refs";
|
|
@@ -347,6 +372,15 @@ create policy "smoodly_write" on "pages" for all
|
|
|
347
372
|
|
|
348
373
|
drop policy if exists "smoodly_read" on "pages";
|
|
349
374
|
create policy "smoodly_read" on "pages" for select
|
|
375
|
+
using ("space_id" = (select "smoodly_current_space"()) and not (select "smoodly_space_key_revoked"()) and exists (select 1 from "page_locales" l where l."page_id" = "pages"."id" and l."status" = 'published'));
|
|
376
|
+
|
|
377
|
+
drop policy if exists "smoodly_write" on "page_locales";
|
|
378
|
+
create policy "smoodly_write" on "page_locales" for all
|
|
379
|
+
using ("space_id" = (select "smoodly_current_space"()) and not (select "smoodly_space_key_revoked"()) and (select "smoodly_key_kind"()) = 'write')
|
|
380
|
+
with check ("space_id" = (select "smoodly_current_space"()) and not (select "smoodly_space_key_revoked"()) and (select "smoodly_key_kind"()) = 'write');
|
|
381
|
+
|
|
382
|
+
drop policy if exists "smoodly_read" on "page_locales";
|
|
383
|
+
create policy "smoodly_read" on "page_locales" for select
|
|
350
384
|
using ("space_id" = (select "smoodly_current_space"()) and not (select "smoodly_space_key_revoked"()) and "status" = 'published');
|
|
351
385
|
|
|
352
386
|
drop policy if exists "smoodly_write" on "page_versions";
|
|
@@ -356,30 +390,34 @@ create policy "smoodly_write" on "page_versions" for all
|
|
|
356
390
|
|
|
357
391
|
drop policy if exists "smoodly_read" on "page_versions";
|
|
358
392
|
create policy "smoodly_read" on "page_versions" for select
|
|
359
|
-
using ("space_id" = (select "smoodly_current_space"()) and not (select "smoodly_space_key_revoked"()) and exists (select 1 from "
|
|
393
|
+
using ("space_id" = (select "smoodly_current_space"()) and not (select "smoodly_space_key_revoked"()) and exists (select 1 from "page_locales" l where l."published_version_id" = "page_versions"."id"));
|
|
360
394
|
|
|
361
|
-
drop policy if exists "smoodly_write" on "
|
|
362
|
-
create policy "smoodly_write" on "
|
|
395
|
+
drop policy if exists "smoodly_write" on "entries";
|
|
396
|
+
create policy "smoodly_write" on "entries" for all
|
|
363
397
|
using ("space_id" = (select "smoodly_current_space"()) and not (select "smoodly_space_key_revoked"()) and (select "smoodly_key_kind"()) = 'write')
|
|
364
398
|
with check ("space_id" = (select "smoodly_current_space"()) and not (select "smoodly_space_key_revoked"()) and (select "smoodly_key_kind"()) = 'write');
|
|
365
399
|
|
|
366
|
-
drop policy if exists "
|
|
367
|
-
create policy "
|
|
400
|
+
drop policy if exists "smoodly_read" on "entries";
|
|
401
|
+
create policy "smoodly_read" on "entries" for select
|
|
402
|
+
using ("space_id" = (select "smoodly_current_space"()) and not (select "smoodly_space_key_revoked"()) and exists (select 1 from "entry_locales" l where l."entry_id" = "entries"."id" and l."status" = 'published'));
|
|
403
|
+
|
|
404
|
+
drop policy if exists "smoodly_write" on "entry_locales";
|
|
405
|
+
create policy "smoodly_write" on "entry_locales" for all
|
|
368
406
|
using ("space_id" = (select "smoodly_current_space"()) and not (select "smoodly_space_key_revoked"()) and (select "smoodly_key_kind"()) = 'write')
|
|
369
407
|
with check ("space_id" = (select "smoodly_current_space"()) and not (select "smoodly_space_key_revoked"()) and (select "smoodly_key_kind"()) = 'write');
|
|
370
408
|
|
|
371
|
-
drop policy if exists "smoodly_read" on "
|
|
372
|
-
create policy "smoodly_read" on "
|
|
373
|
-
using ("space_id" = (select "smoodly_current_space"()) and not (select "smoodly_space_key_revoked"()));
|
|
409
|
+
drop policy if exists "smoodly_read" on "entry_locales";
|
|
410
|
+
create policy "smoodly_read" on "entry_locales" for select
|
|
411
|
+
using ("space_id" = (select "smoodly_current_space"()) and not (select "smoodly_space_key_revoked"()) and "status" = 'published');
|
|
374
412
|
|
|
375
|
-
drop policy if exists "smoodly_write" on "
|
|
376
|
-
create policy "smoodly_write" on "
|
|
413
|
+
drop policy if exists "smoodly_write" on "entry_versions";
|
|
414
|
+
create policy "smoodly_write" on "entry_versions" for all
|
|
377
415
|
using ("space_id" = (select "smoodly_current_space"()) and not (select "smoodly_space_key_revoked"()) and (select "smoodly_key_kind"()) = 'write')
|
|
378
416
|
with check ("space_id" = (select "smoodly_current_space"()) and not (select "smoodly_space_key_revoked"()) and (select "smoodly_key_kind"()) = 'write');
|
|
379
417
|
|
|
380
|
-
drop policy if exists "smoodly_read" on "
|
|
381
|
-
create policy "smoodly_read" on "
|
|
382
|
-
using ("space_id" = (select "smoodly_current_space"()) and not (select "smoodly_space_key_revoked"()) and "
|
|
418
|
+
drop policy if exists "smoodly_read" on "entry_versions";
|
|
419
|
+
create policy "smoodly_read" on "entry_versions" for select
|
|
420
|
+
using ("space_id" = (select "smoodly_current_space"()) and not (select "smoodly_space_key_revoked"()) and exists (select 1 from "entry_locales" l where l."published_version_id" = "entry_versions"."id"));
|
|
383
421
|
|
|
384
422
|
drop policy if exists "smoodly_write" on "refs";
|
|
385
423
|
create policy "smoodly_write" on "refs" for all
|
|
@@ -393,7 +431,7 @@ create policy "smoodly_write" on "paths" for all
|
|
|
393
431
|
|
|
394
432
|
drop policy if exists "smoodly_read" on "paths";
|
|
395
433
|
create policy "smoodly_read" on "paths" for select
|
|
396
|
-
using ("space_id" = (select "smoodly_current_space"()) and not (select "smoodly_space_key_revoked"()) and (("kind" = 'page' and exists (select 1 from "
|
|
434
|
+
using ("space_id" = (select "smoodly_current_space"()) and not (select "smoodly_space_key_revoked"()) and (("kind" = 'page' and exists (select 1 from "page_locales" l where l."page_id" = "paths"."target_id" and l."locale" = "paths"."locale" and l."status" = 'published')) or ("kind" = 'entry' and exists (select 1 from "entry_locales" l where l."entry_id" = "paths"."target_id" and l."locale" = "paths"."locale" and l."status" = 'published'))));
|
|
397
435
|
|
|
398
436
|
drop policy if exists "smoodly_write" on "editors";
|
|
399
437
|
create policy "smoodly_write" on "editors" for all
|
|
@@ -402,26 +440,30 @@ create policy "smoodly_write" on "editors" for all
|
|
|
402
440
|
|
|
403
441
|
create or replace view "people" with (security_invoker = true) as
|
|
404
442
|
select
|
|
405
|
-
"id",
|
|
406
|
-
"
|
|
407
|
-
"
|
|
408
|
-
"
|
|
409
|
-
"
|
|
410
|
-
"
|
|
411
|
-
"fields"->>'
|
|
412
|
-
|
|
413
|
-
|
|
443
|
+
e."id",
|
|
444
|
+
l."locale",
|
|
445
|
+
l."slug",
|
|
446
|
+
e."sort",
|
|
447
|
+
e."created_at",
|
|
448
|
+
l."updated_at",
|
|
449
|
+
e."fields"->>'name' as "name",
|
|
450
|
+
l."fields"->>'role' as "role"
|
|
451
|
+
from "entries" e
|
|
452
|
+
join "entry_locales" l on l."entry_id" = e."id"
|
|
453
|
+
where e."collection" = 'people' and l."status" = 'published';
|
|
414
454
|
|
|
415
455
|
create or replace view "articles" with (security_invoker = true) as
|
|
416
456
|
select
|
|
417
|
-
"id",
|
|
418
|
-
"
|
|
419
|
-
"
|
|
420
|
-
"
|
|
421
|
-
"
|
|
422
|
-
"
|
|
423
|
-
"fields"->>'
|
|
424
|
-
"fields"->>'excerpt' as "excerpt",
|
|
425
|
-
"fields"->>'author' as "author"
|
|
426
|
-
from "entries"
|
|
427
|
-
|
|
457
|
+
e."id",
|
|
458
|
+
l."locale",
|
|
459
|
+
l."slug",
|
|
460
|
+
e."sort",
|
|
461
|
+
e."created_at",
|
|
462
|
+
l."updated_at",
|
|
463
|
+
v."fields"->>'title' as "title",
|
|
464
|
+
v."fields"->>'excerpt' as "excerpt",
|
|
465
|
+
v."fields"->>'author' as "author"
|
|
466
|
+
from "entries" e
|
|
467
|
+
join "entry_locales" l on l."entry_id" = e."id"
|
|
468
|
+
join "entry_versions" v on v."id" = l."published_version_id"
|
|
469
|
+
where e."collection" = 'articles' and l."status" = 'published';
|