@bygghammar/cms-platform 0.11.0 → 0.13.0
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/migrations/20260728113741_f9744b19-078b-46e5-b00f-31c84aaf71ab.sql +111 -0
- package/migrations/20260728113757_4156a886-21fb-4a1f-9c12-acb7bb145102.sql +5 -0
- package/migrations/20260728113823_6e0237e1-99e3-4e1a-8a68-804b7bcdbbb8.sql +1 -0
- package/migrations/20260728115305_506d92b4-129f-4d2b-961f-cf76e592677e.sql +92 -0
- package/migrations/20260728115320_717d4447-f433-4a1d-89d2-fc8f028d4ac6.sql +1 -0
- package/migrations/20260728115347_c77f5a56-19db-4117-bb60-9ad692b817ab.sql +11 -0
- package/migrations/20260728132052_b692dcfe-a944-4a19-afd0-187f7600feb8.sql +63 -0
- package/migrations/20260728183318_05b05a47-ba05-4a66-ab8f-69f2688fea84.sql +209 -0
- package/migrations/20260728193035_84b68d27-c3f3-4516-a3a9-15fc6f476163.sql +17 -0
- package/migrations/20260728193707_8438ee2d-d589-4048-86e2-464fd209af80.sql +37 -0
- package/migrations/20260729055312_08862d7e-0279-4d4f-8709-a59b9f068c55.sql +5 -0
- package/migrations/20260729055348_418b7e36-4877-4304-831f-290ca73e56f3.sql +133 -0
- package/migrations/20260729055358_20b467e2-4efd-42c1-bd34-773ed6b77fc5.sql +3 -0
- package/migrations/20260729061039_306859eb-a38c-44ef-af1a-6c02a8fd84db.sql +43 -0
- package/migrations/20260730065600_54c25861-3355-4600-a72f-3d67b457ecb1.sql +54 -0
- package/migrations/20260730071745_d4904314-15ff-4c58-ac66-85e7371e04b5.sql +113 -0
- package/migrations/20260730071914_48163aa3-830e-4dcc-bdd4-c35be282ab87.sql +22 -0
- package/migrations/20260730085949_bcfc3270-ea80-4617-86a3-2555ed34a280.sql +24 -0
- package/migrations/20260730095256_c977c30e-b285-4041-8804-c0bd72b6d9b3.sql +13 -0
- package/migrations/20260730100057_e341b887-eb0e-4a74-850e-0ee5ffb70d7a.sql +38 -0
- package/migrations/20260730103703_d5c4e1b7-1e2c-4dd0-be4e-185c159ade69.sql +62 -0
- package/migrations/20260730105635_3557b7da-919e-48db-8c92-8221d68d3cf9.sql +29 -0
- package/migrations/20260730120308_12ff8cfb-43f9-4070-abde-61531ad3b75f.sql +73 -0
- package/migrations/20260730125024_1baf8926-12a2-48f4-8edc-7309941309e9.sql +18 -0
- package/migrations/20260730173510_feb974d1-510e-4f52-9e20-5fd0582d8952.sql +107 -0
- package/migrations/20260730175409_9f60743f-f5e1-418c-a700-c91fb3704db8.sql +9 -0
- package/migrations/20260730181224_1c52ff16-c7a2-4ef1-a0a8-e493c2c9106f.sql +7 -0
- package/migrations/20260730183129_933adb75-f985-4d82-ad5d-213b69fd42e5.sql +32 -0
- package/migrations/20260730183918_7bc7a827-2100-49f1-bc6e-24509249350b.sql +68 -0
- package/migrations/20260730202628_7ceade5e-644c-4bc2-91b8-594133329f31.sql +1 -0
- package/migrations/20260730211056_57f42049-00b4-473b-a2cd-65a13570b8d2.sql +16 -0
- package/migrations/20260730214340_98af2e55-9031-4c11-9659-c47a37a8d6b7.sql +1 -0
- package/migrations/20260731091630_8a6f28ce-5833-4901-ab17-27648cef32ec.sql +149 -0
- package/migrations/20260731094716_4c68a1df-83ed-4ba8-8019-fa2fe2b9681e.sql +65 -0
- package/migrations/20260731191655_fef97c3c-1397-47b4-8b56-afb020298e97.sql +165 -0
- package/migrations/20260731192212_95772a2f-19a1-4013-b463-2eb161e96737.sql +135 -0
- package/migrations/20260731192815_c490653e-1232-4ad9-a150-3c83d2b90f5e.sql +13 -0
- package/migrations/20260731193135_7966e740-5e86-4b14-8e1d-5119069666ba.sql +2 -0
- package/migrations/20260731193245_599790d0-ca5e-4b5d-a3e7-d69b2a79e1a3.sql +13 -0
- package/migrations/20260731212959_a748cb0d-4dc7-45dc-be90-f6bacbfab26c.sql +9 -0
- package/migrations/20260801003057_1195f4c1-fb54-42dc-9718-638a25e6a82e.sql +3 -0
- package/migrations/20260801003300_fc591960-cb41-41cf-837d-2eef23b29ca9.sql +40 -0
- package/migrations/20260802151445_a56b0023-eaf7-41e2-a7fb-d4beddfc587c.sql +3 -0
- package/migrations/20260802202621_d661af8a-8513-4b54-b375-f963ae824c8f.sql +225 -0
- package/migrations/20260802202702_c30cd837-744c-4641-85f1-edd3a7ebbcb6.sql +16 -0
- package/migrations/20260802202720_4418d18d-c851-42dc-9345-78fc330128ae.sql +2 -0
- package/migrations/20260803132514_78ba1f53-c85b-4457-96b1-7d49c5c8b494.sql +34 -0
- package/migrations/20260803181201_28c8aa09-baa8-431c-8338-90b1af9c8172.sql +22 -0
- package/migrations/20260803201518_6e8a6028-b70f-4a7d-8bc9-95c86304e7ae.sql +12 -0
- package/migrations/20260803201535_32a9a213-cb92-4035-b8cd-8211ca34af68.sql +12 -0
- package/migrations/20260811103505_29df753d-14fa-4a05-8fea-f4207785fba3.sql +35 -0
- package/migrations/20260811112455_217c4028-f587-4c98-9e4f-9e6c452ab761.sql +20 -0
- package/migrations/20260811114438_6687d67d-bad3-4803-9638-8b7670d2e5d4.sql +86 -0
- package/migrations/20260811130318_7cb95e95-9baa-40af-8f3f-de1d4e09cec4.sql +1 -0
- package/migrations/20260811220548_80d99ec2-bd4b-475d-a627-9408bb60ce56.sql +1 -0
- package/migrations/20260811222519_6b040f56-4de3-49e0-92e4-d9deec5ead6a.sql +3 -0
- package/migrations/20260812000000_seed_voyara_content.sql +390 -0
- package/migrations/20260818040722_1bdf1b8f-7fb0-4ae8-8ecf-73f1fadff3c2.sql +2 -0
- package/migrations/20260818040808_69a5e832-57e8-4aa7-aff8-7fd7777faa7c.sql +15 -0
- package/migrations/20260818040839_e6523163-bbf5-4a39-9233-91759059569a.sql +26 -0
- package/package.json +9 -4
- package/src/backoffice/media/ReviewImageUpload.tsx +104 -0
- package/src/backoffice/seo/PageSeoPanelView.tsx +406 -0
- package/src/platform/contract.ts +92 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
CREATE OR REPLACE FUNCTION app.current_user_id()
|
|
2
|
+
RETURNS uuid
|
|
3
|
+
LANGUAGE sql
|
|
4
|
+
STABLE
|
|
5
|
+
SECURITY INVOKER
|
|
6
|
+
SET search_path = auth, public, pg_temp
|
|
7
|
+
AS $$
|
|
8
|
+
SELECT auth.uid()
|
|
9
|
+
$$;
|
|
10
|
+
|
|
11
|
+
REVOKE ALL ON FUNCTION app.has_role(uuid, public.app_role) FROM PUBLIC, anon, authenticated;
|
|
12
|
+
REVOKE ALL ON FUNCTION app.is_staff(uuid) FROM PUBLIC, anon, authenticated;
|
|
13
|
+
GRANT EXECUTE ON FUNCTION app.has_role(uuid, public.app_role) TO service_role;
|
|
14
|
+
GRANT EXECUTE ON FUNCTION app.is_staff(uuid) TO service_role;
|
|
15
|
+
|
|
16
|
+
GRANT EXECUTE ON FUNCTION app.current_user_id() TO anon, authenticated, service_role;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
-- Least-privilege public read on forms.
|
|
2
|
+
-- Visitors must never be able to read private_settings (notification
|
|
3
|
+
-- recipients, webhook secrets, spreadsheet ids). The original migration
|
|
4
|
+
-- granted only a column subset; some environments drifted to a table-wide
|
|
5
|
+
-- grant. Re-assert the column list here so hosted and self-hosted match.
|
|
6
|
+
REVOKE ALL ON public.forms FROM anon;
|
|
7
|
+
GRANT SELECT (id, key, name, form_type, fields, public_settings, is_active, deleted_at)
|
|
8
|
+
ON public.forms TO anon;
|
|
9
|
+
|
|
10
|
+
-- The public renderer needs exactly two values out of private_settings.
|
|
11
|
+
-- Expose them through a security-definer function instead of widening the
|
|
12
|
+
-- column grant.
|
|
13
|
+
CREATE OR REPLACE FUNCTION public.form_public_runtime(_key text)
|
|
14
|
+
RETURNS jsonb
|
|
15
|
+
LANGUAGE sql
|
|
16
|
+
STABLE
|
|
17
|
+
SECURITY DEFINER
|
|
18
|
+
SET search_path = public
|
|
19
|
+
AS $$
|
|
20
|
+
SELECT jsonb_strip_nulls(
|
|
21
|
+
jsonb_build_object(
|
|
22
|
+
'spamMinSeconds', f.private_settings -> 'spamMinSeconds',
|
|
23
|
+
'savePartials', f.private_settings -> 'savePartials'
|
|
24
|
+
)
|
|
25
|
+
)
|
|
26
|
+
FROM public.forms f
|
|
27
|
+
WHERE f.key = _key
|
|
28
|
+
AND f.is_active = true
|
|
29
|
+
AND f.deleted_at IS NULL
|
|
30
|
+
LIMIT 1
|
|
31
|
+
$$;
|
|
32
|
+
|
|
33
|
+
REVOKE ALL ON FUNCTION public.form_public_runtime(text) FROM PUBLIC;
|
|
34
|
+
GRANT EXECUTE ON FUNCTION public.form_public_runtime(text) TO anon, authenticated, service_role;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
CREATE OR REPLACE FUNCTION public.form_public_runtime(_key text)
|
|
2
|
+
RETURNS jsonb
|
|
3
|
+
LANGUAGE sql
|
|
4
|
+
STABLE
|
|
5
|
+
SECURITY DEFINER
|
|
6
|
+
SET search_path = ''
|
|
7
|
+
AS $$
|
|
8
|
+
SELECT pg_catalog.jsonb_strip_nulls(
|
|
9
|
+
pg_catalog.jsonb_build_object(
|
|
10
|
+
'spamMinSeconds', f.private_settings -> 'spamMinSeconds',
|
|
11
|
+
'savePartials', f.private_settings -> 'savePartials'
|
|
12
|
+
)
|
|
13
|
+
)
|
|
14
|
+
FROM public.forms f
|
|
15
|
+
WHERE f.key = _key
|
|
16
|
+
AND f.is_active = true
|
|
17
|
+
AND f.deleted_at IS NULL
|
|
18
|
+
LIMIT 1
|
|
19
|
+
$$;
|
|
20
|
+
|
|
21
|
+
REVOKE ALL ON FUNCTION public.form_public_runtime(text) FROM PUBLIC;
|
|
22
|
+
GRANT EXECUTE ON FUNCTION public.form_public_runtime(text) TO anon, authenticated, service_role;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
-- Neutralised: this migration originally hardcoded an absolute hosted storage
|
|
2
|
+
-- URL for the homepage hero poster. Absolute hosted URLs are not portable and
|
|
3
|
+
-- must never reach a self-hosted database (this directory is replayed by
|
|
4
|
+
-- deploy/initdb/10-schema.sh on a fresh PostgreSQL volume).
|
|
5
|
+
--
|
|
6
|
+
-- The portable replacement lives in db/selfhost/upgrades/0002_optimized_hero_media.sql
|
|
7
|
+
-- and is applied by scripts/install-media-package.ts, which first verifies that
|
|
8
|
+
-- the optimized media actually exists in the media volume.
|
|
9
|
+
--
|
|
10
|
+
-- Hosted behaviour is preserved: the hosted database already ran the original
|
|
11
|
+
-- statement, and its rows were rewritten to site-relative /media/ paths.
|
|
12
|
+
SELECT 1;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
-- Neutralised: this migration originally hardcoded an absolute hosted storage
|
|
2
|
+
-- URL for the homepage hero poster. Absolute hosted URLs are not portable and
|
|
3
|
+
-- must never reach a self-hosted database (this directory is replayed by
|
|
4
|
+
-- deploy/initdb/10-schema.sh on a fresh PostgreSQL volume).
|
|
5
|
+
--
|
|
6
|
+
-- The portable replacement lives in db/selfhost/upgrades/0002_optimized_hero_media.sql
|
|
7
|
+
-- and is applied by scripts/install-media-package.ts, which first verifies that
|
|
8
|
+
-- the optimized media actually exists in the media volume.
|
|
9
|
+
--
|
|
10
|
+
-- Hosted behaviour is preserved: the hosted database already ran the original
|
|
11
|
+
-- statement, and its rows were rewritten to site-relative /media/ paths.
|
|
12
|
+
SELECT 1;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
-- These policies and triggers were introduced by earlier migrations. Reassert
|
|
2
|
+
-- their final definitions idempotently so a fresh database can replay the
|
|
3
|
+
-- complete Lovable migration history without failing on duplicate objects.
|
|
4
|
+
DROP POLICY IF EXISTS "Admins can read media" ON storage.objects;
|
|
5
|
+
CREATE POLICY "Admins can read media"
|
|
6
|
+
ON storage.objects FOR SELECT TO authenticated
|
|
7
|
+
USING (bucket_id = 'media' AND public.has_role(auth.uid(), 'admin'));
|
|
8
|
+
|
|
9
|
+
DROP POLICY IF EXISTS "Admins can upload media" ON storage.objects;
|
|
10
|
+
CREATE POLICY "Admins can upload media"
|
|
11
|
+
ON storage.objects FOR INSERT TO authenticated
|
|
12
|
+
WITH CHECK (bucket_id = 'media' AND public.has_role(auth.uid(), 'admin'));
|
|
13
|
+
|
|
14
|
+
DROP POLICY IF EXISTS "Admins can update media" ON storage.objects;
|
|
15
|
+
CREATE POLICY "Admins can update media"
|
|
16
|
+
ON storage.objects FOR UPDATE TO authenticated
|
|
17
|
+
USING (bucket_id = 'media' AND public.has_role(auth.uid(), 'admin'))
|
|
18
|
+
WITH CHECK (bucket_id = 'media' AND public.has_role(auth.uid(), 'admin'));
|
|
19
|
+
|
|
20
|
+
DROP POLICY IF EXISTS "Admins can delete media" ON storage.objects;
|
|
21
|
+
CREATE POLICY "Admins can delete media"
|
|
22
|
+
ON storage.objects FOR DELETE TO authenticated
|
|
23
|
+
USING (bucket_id = 'media' AND public.has_role(auth.uid(), 'admin'));
|
|
24
|
+
|
|
25
|
+
DROP TRIGGER IF EXISTS on_auth_user_created_grant_admin ON auth.users;
|
|
26
|
+
CREATE TRIGGER on_auth_user_created_grant_admin
|
|
27
|
+
AFTER INSERT ON auth.users
|
|
28
|
+
FOR EACH ROW EXECUTE FUNCTION public.grant_initial_admin();
|
|
29
|
+
|
|
30
|
+
DROP TRIGGER IF EXISTS on_auth_user_confirmed_grant_admin ON auth.users;
|
|
31
|
+
CREATE TRIGGER on_auth_user_confirmed_grant_admin
|
|
32
|
+
AFTER UPDATE OF email_confirmed_at ON auth.users
|
|
33
|
+
FOR EACH ROW
|
|
34
|
+
WHEN (OLD.email_confirmed_at IS NULL AND NEW.email_confirmed_at IS NOT NULL)
|
|
35
|
+
EXECUTE FUNCTION public.grant_initial_admin();
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
UPDATE public.page_seo SET seo = jsonb_set(seo, '{title,sv}', to_jsonb(v.title)) FROM (VALUES
|
|
2
|
+
('home','Nordens största partykryssning och festkryssning | Voyara'),
|
|
3
|
+
('artister','Artister på vinterns hetaste partykryssning · Voyara'),
|
|
4
|
+
('hytter','Hytter ombord · Voyara partykryssning'),
|
|
5
|
+
('mat-och-dryck','Mat och dryck på Voyara · Partykryssning'),
|
|
6
|
+
('tallinn','Tallinn · Voyara partykryssning'),
|
|
7
|
+
('sakerhet','Säkerhet och en trygg miljö · Voyara'),
|
|
8
|
+
('galleri','Galleri · Voyara partykryssning'),
|
|
9
|
+
('faq','FAQ · Voyara partykryssning'),
|
|
10
|
+
('boka','Boka nu · Voyara partykryssning'),
|
|
11
|
+
('samarbete','Samarbete · Voyara partykryssning'),
|
|
12
|
+
('ambassador','Bli ambassadör · Voyara partykryssning'),
|
|
13
|
+
('kontakt','Kontakta oss · Voyara'),
|
|
14
|
+
('intresse','Intresseanmälan · Voyara partykryssning')
|
|
15
|
+
) AS v(page_key, title) WHERE public.page_seo.page_key = v.page_key;
|
|
16
|
+
|
|
17
|
+
UPDATE public.page_seo SET seo = jsonb_set(seo, '{description,sv}', to_jsonb(v.descr)) FROM (VALUES
|
|
18
|
+
('home','Välkommen till en festkryssning och partykryssning utöver det vanliga. Artister, DJ:s och shower varje kväll — studenter och alla är välkomna.'),
|
|
19
|
+
('artister','Välkommen till partykryssningen med de hetaste artisterna. Ett unikt nöjeskoncept i två dagar med uppträdanden båda kvällarna.')
|
|
20
|
+
) AS v(page_key, descr) WHERE public.page_seo.page_key = v.page_key;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
begin;
|
|
2
|
+
|
|
3
|
+
with p as (select id from public.pages where key = 'home'),
|
|
4
|
+
cur as (
|
|
5
|
+
select v.blocks from public.page_versions v
|
|
6
|
+
join public.pages pg on pg.current_version_id = v.id
|
|
7
|
+
where pg.key = 'home'
|
|
8
|
+
),
|
|
9
|
+
tiles as (
|
|
10
|
+
select jsonb_build_object(
|
|
11
|
+
'id', 'blk-link-tiles-home',
|
|
12
|
+
'type', 'linkTiles',
|
|
13
|
+
'name', 'Boka / Elevkårer / Ambassadör',
|
|
14
|
+
'props', jsonb_build_object(
|
|
15
|
+
'tone', 'white',
|
|
16
|
+
'columns', 3,
|
|
17
|
+
'gap', 'md',
|
|
18
|
+
'aspect', 'portrait',
|
|
19
|
+
'overlay', 'brand',
|
|
20
|
+
'labelAlign', 'left',
|
|
21
|
+
'rounded', false,
|
|
22
|
+
'items', jsonb_build_array(
|
|
23
|
+
jsonb_build_object(
|
|
24
|
+
'id', 'tile-boka',
|
|
25
|
+
'image', 'https://ybnqylupuisyhuldqrgt.supabase.co/storage/v1/object/public/media/boka-nu.jpg',
|
|
26
|
+
'label', jsonb_build_object('sv', 'Boka nu'),
|
|
27
|
+
'alt', jsonb_build_object('sv', 'Publik framför scenen på Voyara partykryssning'),
|
|
28
|
+
'href', '/boka'
|
|
29
|
+
),
|
|
30
|
+
jsonb_build_object(
|
|
31
|
+
'id', 'tile-elevkarer',
|
|
32
|
+
'image', 'https://ybnqylupuisyhuldqrgt.supabase.co/storage/v1/object/public/media/artister-scen.jpg',
|
|
33
|
+
'label', jsonb_build_object('sv', 'För elevkårer'),
|
|
34
|
+
'alt', jsonb_build_object('sv', 'Artist på scen ombord'),
|
|
35
|
+
'href', '/samarbete'
|
|
36
|
+
),
|
|
37
|
+
jsonb_build_object(
|
|
38
|
+
'id', 'tile-ambassador',
|
|
39
|
+
'image', 'https://ybnqylupuisyhuldqrgt.supabase.co/storage/v1/object/public/media/voyara-publik.jpg',
|
|
40
|
+
'label', jsonb_build_object('sv', 'Bli ambassadör'),
|
|
41
|
+
'alt', jsonb_build_object('sv', 'Gäster som festar ombord'),
|
|
42
|
+
'href', '/ambassador'
|
|
43
|
+
)
|
|
44
|
+
)
|
|
45
|
+
)
|
|
46
|
+
) as blk
|
|
47
|
+
),
|
|
48
|
+
newblocks as (
|
|
49
|
+
select (
|
|
50
|
+
select coalesce(jsonb_agg(x.b order by x.idx), '[]'::jsonb)
|
|
51
|
+
from (
|
|
52
|
+
select b, idx::numeric as idx from cur, lateral jsonb_array_elements(cur.blocks) with ordinality t(b, idx)
|
|
53
|
+
where b->>'type' <> 'linkTiles'
|
|
54
|
+
union all
|
|
55
|
+
select (select blk from tiles),
|
|
56
|
+
coalesce((
|
|
57
|
+
select max(idx) + 0.5 from cur, lateral jsonb_array_elements(cur.blocks) with ordinality t(b, idx)
|
|
58
|
+
where b->>'type' = 'courseList'
|
|
59
|
+
), 999)
|
|
60
|
+
) x
|
|
61
|
+
) as blocks
|
|
62
|
+
),
|
|
63
|
+
ins as (
|
|
64
|
+
insert into public.page_versions (page_id, version_no, blocks, note, created_by_email)
|
|
65
|
+
select p.id,
|
|
66
|
+
coalesce((select max(version_no) from public.page_versions pv where pv.page_id = p.id), 0) + 1,
|
|
67
|
+
(select blocks from newblocks),
|
|
68
|
+
'Add link tiles row (Boka / Elevkårer / Ambassadör)',
|
|
69
|
+
'system'
|
|
70
|
+
from p
|
|
71
|
+
returning id, page_id
|
|
72
|
+
),
|
|
73
|
+
deact as (
|
|
74
|
+
update public.page_publications pp set is_active = false
|
|
75
|
+
where pp.page_id = (select id from p) and pp.is_active
|
|
76
|
+
returning 1
|
|
77
|
+
),
|
|
78
|
+
pub as (
|
|
79
|
+
insert into public.page_publications (page_id, version_id, note)
|
|
80
|
+
select page_id, id, 'Add link tiles row' from ins
|
|
81
|
+
returning page_id, version_id
|
|
82
|
+
)
|
|
83
|
+
update public.pages pg set current_version_id = pub.version_id, updated_at = now()
|
|
84
|
+
from pub where pg.id = pub.page_id;
|
|
85
|
+
|
|
86
|
+
commit;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
UPDATE page_versions v SET blocks = (SELECT jsonb_agg(CASE WHEN b->>'type'='linkTiles' THEN jsonb_set(b, '{props,labelAlign}', '"center"') ELSE b END) FROM jsonb_array_elements(v.blocks) b) FROM pages p WHERE v.id=p.current_version_id AND p.key='home';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
UPDATE public.locale_domains SET domain = 'byggis.voyara.se', updated_at = now() WHERE domain = 'www.dev.barskola.nu';
|