diff --git a/.env.example b/.env.example
new file mode 100644
index 0000000..532f804
--- /dev/null
+++ b/.env.example
@@ -0,0 +1,13 @@
+# Skopírujte tento súbor ako .env.local a doplňte hodnoty.
+
+# Supabase (Project Settings → API)
+NEXT_PUBLIC_SUPABASE_URL=https://VAS-PROJEKT.supabase.co
+NEXT_PUBLIC_SUPABASE_ANON_KEY=
+# service_role kľúč – len na serveri (nahrávanie obrázkov), nikdy ho nedávajte do kódu pre prehliadač
+SUPABASE_SERVICE_ROLE_KEY=
+
+# Brevo (SMTP & API → API Keys)
+BREVO_API_KEY=
+BREVO_SENDER_NAME=COOP Jednota
+# E-mail odosielateľa musí byť v Brevo overený
+BREVO_SENDER_EMAIL=
diff --git a/.gitignore b/.gitignore
index 2913495..f4eda9d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -49,3 +49,6 @@ docs/
.vercel
.env*
+
+# vzor premenných prostredia sa commituje
+!.env.example
diff --git a/README.md b/README.md
index e215bc4..f0c1f27 100644
--- a/README.md
+++ b/README.md
@@ -1,36 +1,66 @@
-This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app).
+# COOP Jednota – generátor newsletterov
-## Getting Started
+Interný editor e-mailových newsletterov pre COOP Jednota: skladanie kampane z modulov
+(hlavička, bannery, produktové sekcie, vernostné zľavy, letáky, recepty, pätička),
+editor grafických cenoviek, export do ZIP a odoslanie kampane do Brevo.
-First, run the development server:
+Technológie: Next.js 16, React 19, Tailwind CSS 4, Supabase (databáza + úložisko obrázkov), Brevo API.
+
+## Inštalácia na nový server
+
+### 1. Supabase projekt
+
+1. Vytvorte nový projekt na [supabase.com](https://supabase.com) (alebo použite vlastný Supabase server).
+2. **Databáza:** otvorte *SQL Editor*, vložte celý obsah [`supabase/schema.sql`](supabase/schema.sql) a kliknite *Run*.
+ Vytvoria sa tabuľky `templates` (kampane) a `badges` (šablóny cenoviek), prístupové pravidlá
+ a verejné úložisko obrázkov `newsletter-assets`. Skript sa dá bezpečne spustiť aj opakovane.
+3. V *Project Settings → API* si skopírujte **Project URL**, **anon** kľúč a **service_role** kľúč.
+
+### 2. Premenné prostredia
```bash
-npm run dev
-# or
-yarn dev
-# or
-pnpm dev
-# or
-bun dev
+cp .env.example .env.local
```
-Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
+Doplňte do `.env.local` údaje zo Supabase a Brevo (popis je priamo v súbore).
+Na hostingu (Vercel, Docker…) nastavte rovnaké premenné v jeho nastaveniach.
-You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
+### 3. Inštalácia a statické obrázky
-This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel.
+```bash
+npm install
+npm run db:upload-assets
+```
-## Learn More
+Druhý príkaz nahrá do úložiska `newsletter-assets` logá, ikony sociálnych sietí, štítky predajní
+a ukážkové obrázky zo [`supabase/assets/`](supabase/assets/), ktoré šablóna newslettera používa.
-To learn more about Next.js, take a look at the following resources:
+### 4. Spustenie
-- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
-- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
+```bash
+npm run dev # vývoj na http://localhost:3000
+npm run build # produkčný build
+npm run start # produkčný server
+```
-You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome!
+Pri prvom spustení s prázdnou databázou sa vytvorí nová kampaň z predvolenej šablóny
+([`src/lib/defaultCampaign.ts`](src/lib/defaultCampaign.ts)) a automaticky sa uloží.
-## Deploy on Vercel
+## Štruktúra projektu
-The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
+| Cesta | Obsah |
+|---|---|
+| `src/app/page.tsx` | Hlavná obrazovka editora (stav kampane, auto-save, náhľad) |
+| `src/components/editor/` | Panel nastavení, editor cenoviek, modály (import, uložené kampane) |
+| `src/lib/emailRenderer.ts` | Generovanie HTML e-mailu z kampane (náhľad aj export) |
+| `src/lib/badgeUtils.ts` | Generovanie SVG cenoviek a premenné (`{cena}`, `{zlava}`, `{cena_s_kartou}`…) |
+| `src/app/api/` | Serverové API: nahrávanie obrázkov, inline CSS, export a overenie kampane v Brevo |
+| `supabase/schema.sql` | Schéma databázy a úložiska |
+| `supabase/assets/` | Statické obrázky šablóny (nahrávajú sa cez `npm run db:upload-assets`) |
-Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details.
+## Poznámky
+
+- Aplikácia nemá prihlasovanie a databáza je prístupná cez anon kľúč – je určená na interné použitie.
+ Ak bude verejne dostupná, treba doplniť autentifikáciu.
+- Kampane uložené v pôvodnom Supabase projekte obsahujú odkazy na obrázky v pôvodnom úložisku.
+ Nové kampane a novo nahraté obrázky používajú úložisko z `.env.local`.
diff --git a/package.json b/package.json
index c732724..a1ef6fe 100644
--- a/package.json
+++ b/package.json
@@ -6,7 +6,8 @@
"dev": "next dev",
"build": "next build",
"start": "next start",
- "lint": "eslint"
+ "lint": "eslint",
+ "db:upload-assets": "node --env-file=.env.local scripts/upload-assets.mjs"
},
"dependencies": {
"@supabase/supabase-js": "^2.117.1",
diff --git a/scripts/upload-assets.mjs b/scripts/upload-assets.mjs
new file mode 100644
index 0000000..d0e93b2
--- /dev/null
+++ b/scripts/upload-assets.mjs
@@ -0,0 +1,45 @@
+// Nahrá statické obrázky aplikácie (supabase/assets/) do Supabase Storage bucketu newsletter-assets.
+// Spustenie: npm run db:upload-assets (číta NEXT_PUBLIC_SUPABASE_URL a SUPABASE_SERVICE_ROLE_KEY z .env.local)
+// Existujúce súbory s rovnakým názvom sa prepíšu.
+import { createClient } from '@supabase/supabase-js';
+import { readdir, readFile } from 'node:fs/promises';
+import path from 'node:path';
+
+const BUCKET = 'newsletter-assets';
+const ASSETS_DIR = path.join(process.cwd(), 'supabase', 'assets');
+const CONTENT_TYPES = {
+ '.png': 'image/png',
+ '.jpg': 'image/jpeg',
+ '.jpeg': 'image/jpeg',
+ '.gif': 'image/gif',
+ '.svg': 'image/svg+xml',
+ '.webp': 'image/webp'
+};
+
+const url = process.env.NEXT_PUBLIC_SUPABASE_URL;
+const serviceKey = process.env.SUPABASE_SERVICE_ROLE_KEY;
+if (!url || !serviceKey) {
+ console.error('Chýba NEXT_PUBLIC_SUPABASE_URL alebo SUPABASE_SERVICE_ROLE_KEY v .env.local');
+ process.exit(1);
+}
+
+const supabase = createClient(url, serviceKey);
+const files = (await readdir(ASSETS_DIR)).filter((f) => CONTENT_TYPES[path.extname(f).toLowerCase()]);
+
+let failed = 0;
+for (const file of files) {
+ const body = await readFile(path.join(ASSETS_DIR, file));
+ const { error } = await supabase.storage.from(BUCKET).upload(file, body, {
+ contentType: CONTENT_TYPES[path.extname(file).toLowerCase()],
+ upsert: true
+ });
+ if (error) {
+ failed++;
+ console.error(`✗ ${file}: ${error.message}`);
+ } else {
+ console.log(`✓ ${file}`);
+ }
+}
+
+console.log(`\nNahraté ${files.length - failed}/${files.length} súborov do bucketu ${BUCKET}.`);
+if (failed) process.exit(1);
diff --git a/src/lib/defaultCampaign.ts b/src/lib/defaultCampaign.ts
index fa79ba7..b42abb2 100644
--- a/src/lib/defaultCampaign.ts
+++ b/src/lib/defaultCampaign.ts
@@ -1,7 +1,8 @@
import { NewsletterCampaign, ProductItem } from '@/types/newsletter';
-export const SUPABASE_ASSETS_BASE =
- 'https://dqexxfspkylqttrtxsww.supabase.co/storage/v1/object/public/newsletter-assets/';
+// Verejné úložisko statických obrázkov (logá, ikony, štítky predajní...) v Supabase projekte z .env.
+// Súbory sú v supabase/assets/ a nahrajú sa príkazom: npm run db:upload-assets
+export const SUPABASE_ASSETS_BASE = `${(process.env.NEXT_PUBLIC_SUPABASE_URL || '').replace(/\/$/, '')}/storage/v1/object/public/newsletter-assets/`;
export const DEFAULT_CAMPAIGN: NewsletterCampaign = {
id: '',
diff --git a/supabase/assets/aktualne_letaky.jpg b/supabase/assets/aktualne_letaky.jpg
new file mode 100644
index 0000000..136b2a3
Binary files /dev/null and b/supabase/assets/aktualne_letaky.jpg differ
diff --git a/supabase/assets/clanky-casopis_jednota.png b/supabase/assets/clanky-casopis_jednota.png
new file mode 100644
index 0000000..bbfbc15
Binary files /dev/null and b/supabase/assets/clanky-casopis_jednota.png differ
diff --git a/supabase/assets/clanky-netradicne_recepty.png b/supabase/assets/clanky-netradicne_recepty.png
new file mode 100644
index 0000000..823bbdb
Binary files /dev/null and b/supabase/assets/clanky-netradicne_recepty.png differ
diff --git a/supabase/assets/clanok_barancek.png b/supabase/assets/clanok_barancek.png
new file mode 100644
index 0000000..2129243
Binary files /dev/null and b/supabase/assets/clanok_barancek.png differ
diff --git a/supabase/assets/clanok_vajicka.png b/supabase/assets/clanok_vajicka.png
new file mode 100644
index 0000000..9d53ce2
Binary files /dev/null and b/supabase/assets/clanok_vajicka.png differ
diff --git a/supabase/assets/ikona_fb.png b/supabase/assets/ikona_fb.png
new file mode 100644
index 0000000..1c9f65d
Binary files /dev/null and b/supabase/assets/ikona_fb.png differ
diff --git a/supabase/assets/ikona_ig.png b/supabase/assets/ikona_ig.png
new file mode 100644
index 0000000..e4b83d5
Binary files /dev/null and b/supabase/assets/ikona_ig.png differ
diff --git a/supabase/assets/ikona_tt.png b/supabase/assets/ikona_tt.png
new file mode 100644
index 0000000..dc75d2d
Binary files /dev/null and b/supabase/assets/ikona_tt.png differ
diff --git a/supabase/assets/ikona_yt.png b/supabase/assets/ikona_yt.png
new file mode 100644
index 0000000..c5995ba
Binary files /dev/null and b/supabase/assets/ikona_yt.png differ
diff --git a/supabase/assets/logo-COOP_nadacia.png b/supabase/assets/logo-COOP_nadacia.png
new file mode 100644
index 0000000..f29c6f1
Binary files /dev/null and b/supabase/assets/logo-COOP_nadacia.png differ
diff --git a/supabase/assets/logo-app_store.png b/supabase/assets/logo-app_store.png
new file mode 100644
index 0000000..29043c0
Binary files /dev/null and b/supabase/assets/logo-app_store.png differ
diff --git a/supabase/assets/logo-google_play.png b/supabase/assets/logo-google_play.png
new file mode 100644
index 0000000..0ef7b65
Binary files /dev/null and b/supabase/assets/logo-google_play.png differ
diff --git a/supabase/assets/logo-netradicne_recepty.png b/supabase/assets/logo-netradicne_recepty.png
new file mode 100644
index 0000000..6860606
Binary files /dev/null and b/supabase/assets/logo-netradicne_recepty.png differ
diff --git a/supabase/assets/logo_coop.png b/supabase/assets/logo_coop.png
new file mode 100644
index 0000000..14fdb85
Binary files /dev/null and b/supabase/assets/logo_coop.png differ
diff --git a/supabase/assets/nws_podklady-nove_obaly.jpg b/supabase/assets/nws_podklady-nove_obaly.jpg
new file mode 100644
index 0000000..c0de395
Binary files /dev/null and b/supabase/assets/nws_podklady-nove_obaly.jpg differ
diff --git a/supabase/assets/nws_podklady-velka_noc.jpg b/supabase/assets/nws_podklady-velka_noc.jpg
new file mode 100644
index 0000000..70a1a54
Binary files /dev/null and b/supabase/assets/nws_podklady-velka_noc.jpg differ
diff --git a/supabase/assets/online_letak.jpg b/supabase/assets/online_letak.jpg
new file mode 100644
index 0000000..d61a738
Binary files /dev/null and b/supabase/assets/online_letak.jpg differ
diff --git a/supabase/assets/produkt_1.png b/supabase/assets/produkt_1.png
new file mode 100644
index 0000000..fde30b8
Binary files /dev/null and b/supabase/assets/produkt_1.png differ
diff --git a/supabase/assets/produkt_2.png b/supabase/assets/produkt_2.png
new file mode 100644
index 0000000..1cdf2e3
Binary files /dev/null and b/supabase/assets/produkt_2.png differ
diff --git a/supabase/assets/produkt_3.png b/supabase/assets/produkt_3.png
new file mode 100644
index 0000000..be6557c
Binary files /dev/null and b/supabase/assets/produkt_3.png differ
diff --git a/supabase/assets/produkt_4.png b/supabase/assets/produkt_4.png
new file mode 100644
index 0000000..53d5511
Binary files /dev/null and b/supabase/assets/produkt_4.png differ
diff --git a/supabase/assets/produkt_5.png b/supabase/assets/produkt_5.png
new file mode 100644
index 0000000..e2e0fec
Binary files /dev/null and b/supabase/assets/produkt_5.png differ
diff --git a/supabase/assets/produkt_6.png b/supabase/assets/produkt_6.png
new file mode 100644
index 0000000..fd6a940
Binary files /dev/null and b/supabase/assets/produkt_6.png differ
diff --git a/supabase/assets/stit_potraviny.png b/supabase/assets/stit_potraviny.png
new file mode 100644
index 0000000..9a55ebb
Binary files /dev/null and b/supabase/assets/stit_potraviny.png differ
diff --git a/supabase/assets/stit_supermarket.png b/supabase/assets/stit_supermarket.png
new file mode 100644
index 0000000..c1a0d34
Binary files /dev/null and b/supabase/assets/stit_supermarket.png differ
diff --git a/supabase/assets/stit_tempo.png b/supabase/assets/stit_tempo.png
new file mode 100644
index 0000000..8387f82
Binary files /dev/null and b/supabase/assets/stit_tempo.png differ
diff --git a/supabase/assets/vernostna_karta-hlavicka_transparent.png b/supabase/assets/vernostna_karta-hlavicka_transparent.png
new file mode 100644
index 0000000..b627aa1
Binary files /dev/null and b/supabase/assets/vernostna_karta-hlavicka_transparent.png differ
diff --git a/supabase/assets/vernostna_karta-produkt_1.png b/supabase/assets/vernostna_karta-produkt_1.png
new file mode 100644
index 0000000..ce0f1a5
Binary files /dev/null and b/supabase/assets/vernostna_karta-produkt_1.png differ
diff --git a/supabase/assets/vernostna_karta-produkt_2.png b/supabase/assets/vernostna_karta-produkt_2.png
new file mode 100644
index 0000000..fd5f184
Binary files /dev/null and b/supabase/assets/vernostna_karta-produkt_2.png differ
diff --git a/supabase/schema.sql b/supabase/schema.sql
new file mode 100644
index 0000000..e7cef79
--- /dev/null
+++ b/supabase/schema.sql
@@ -0,0 +1,61 @@
+-- Schéma pre Modulárny generátor newsletterov (COOP Jednota)
+--
+-- Založenie databázy na novom Supabase projekte:
+-- Supabase Dashboard → SQL Editor → vložiť celý tento súbor → Run.
+-- Skript je idempotentný – dá sa spustiť opakovane bez straty dát.
+
+-- 1. Tabuľka šablón / konceptov newslettera
+-- data = { preheader, modules[] } – celý obsah kampane ako JSON
+CREATE TABLE IF NOT EXISTS templates (
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
+ title TEXT NOT NULL DEFAULT 'Nový newsletter',
+ status TEXT NOT NULL DEFAULT 'draft' CHECK (status IN ('draft', 'ready', 'exported')),
+ data JSONB NOT NULL DEFAULT '{}'::jsonb,
+ brevo_campaign_id INTEGER,
+ created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
+ updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
+);
+
+-- Index pre rýchle zoradenie podľa dátumu úpravy
+CREATE INDEX IF NOT EXISTS idx_templates_updated_at ON templates(updated_at DESC);
+
+-- 2. Tabuľka šablón cenoviek (Badges)
+-- layers_config = { layers[], width, align, paddingTop, paddingBottom }
+-- (staršie záznamy môžu mať len pole vrstiev – aplikácia podporuje oba tvary)
+CREATE TABLE IF NOT EXISTS badges (
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
+ name TEXT NOT NULL,
+ svg_background_url TEXT,
+ svg_raw TEXT,
+ layers_config JSONB NOT NULL DEFAULT '[]'::jsonb,
+ preview_image_url TEXT,
+ created_at TIMESTAMPTZ NOT NULL DEFAULT now()
+);
+
+-- 3. Tabuľka uložených profilov mapovania importu (zatiaľ nevyužitá aplikáciou)
+CREATE TABLE IF NOT EXISTS mapping_presets (
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
+ name TEXT NOT NULL,
+ file_type TEXT NOT NULL CHECK (file_type IN ('csv', 'json', 'xml')),
+ mapping_rules JSONB NOT NULL DEFAULT '{}'::jsonb,
+ created_at TIMESTAMPTZ NOT NULL DEFAULT now()
+);
+
+-- 4. RLS (Row Level Security) – interný nástroj: povolený prístup cez anon kľúč
+ALTER TABLE templates ENABLE ROW LEVEL SECURITY;
+ALTER TABLE badges ENABLE ROW LEVEL SECURITY;
+ALTER TABLE mapping_presets ENABLE ROW LEVEL SECURITY;
+
+DROP POLICY IF EXISTS "Allow public all on templates" ON templates;
+DROP POLICY IF EXISTS "Allow public all on badges" ON badges;
+DROP POLICY IF EXISTS "Allow public all on mapping_presets" ON mapping_presets;
+
+CREATE POLICY "Allow public all on templates" ON templates FOR ALL USING (true) WITH CHECK (true);
+CREATE POLICY "Allow public all on badges" ON badges FOR ALL USING (true) WITH CHECK (true);
+CREATE POLICY "Allow public all on mapping_presets" ON mapping_presets FOR ALL USING (true) WITH CHECK (true);
+
+-- 5. Úložisko obrázkov (Storage bucket) – verejne čitateľné, aby sa obrázky zobrazili v e-mailoch.
+-- Nahrávanie ide cez /api/upload so service_role kľúčom (obchádza RLS), ďalšie politiky netreba.
+INSERT INTO storage.buckets (id, name, public)
+VALUES ('newsletter-assets', 'newsletter-assets', true)
+ON CONFLICT (id) DO UPDATE SET public = true;
diff --git a/supabase_migration.sql b/supabase_migration.sql
deleted file mode 100644
index 1b52e9a..0000000
--- a/supabase_migration.sql
+++ /dev/null
@@ -1,72 +0,0 @@
--- Schéma pre Modulárny generátor newsletterov (COOP Jednota)
-
--- 1. Tabuľka šablón / konceptov newslettera
-CREATE TABLE IF NOT EXISTS templates (
- id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
- title TEXT NOT NULL DEFAULT 'Nový newsletter',
- status TEXT NOT NULL DEFAULT 'draft' CHECK (status IN ('draft', 'ready', 'exported')),
- data JSONB NOT NULL DEFAULT '{}'::jsonb,
- brevo_campaign_id INTEGER,
- created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
- updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
-);
-
--- Index pre rýchle zoradenie podľa dátumu úpravy
-CREATE INDEX IF NOT EXISTS idx_templates_updated_at ON templates(updated_at DESC);
-
--- 2. Tabuľka cenoviek (Badges)
-CREATE TABLE IF NOT EXISTS badges (
- id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
- name TEXT NOT NULL,
- svg_background_url TEXT,
- svg_raw TEXT,
- layers_config JSONB NOT NULL DEFAULT '[]'::jsonb,
- preview_image_url TEXT,
- created_at TIMESTAMPTZ NOT NULL DEFAULT now()
-);
-
--- 3. Tabuľka uložených profilov mapovania (Data Mapper Presets)
-CREATE TABLE IF NOT EXISTS mapping_presets (
- id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
- name TEXT NOT NULL,
- file_type TEXT NOT NULL CHECK (file_type IN ('csv', 'json', 'xml')),
- mapping_rules JSONB NOT NULL DEFAULT '{}'::jsonb,
- created_at TIMESTAMPTZ NOT NULL DEFAULT now()
-);
-
--- 4. Východiskové referenčné cenovky (Seed dát pre COOP Jednota)
-INSERT INTO badges (name, svg_raw, layers_config) VALUES
-(
- 'Žltá AKCIA',
- '',
- '[
- {"id": "l1", "type": "text", "text": "AKCIA", "x": 80, "y": 32, "fontSize": 24, "fontWeight": "900", "fill": "#e0001b", "align": "center"},
- {"id": "l2", "type": "text", "text": "{zlava}", "x": 80, "y": 64, "fontSize": 22, "fontWeight": "800", "fill": "#001a33", "align": "center"}
- ]'::jsonb
-),
-(
- 'Červená SUPER CENA',
- '',
- '[
- {"id": "l1", "type": "text", "text": "SUPER CENA", "x": 80, "y": 34, "fontSize": 18, "fontWeight": "900", "fill": "#ffffff", "align": "center"},
- {"id": "l2", "type": "text", "text": "{zlava}", "x": 80, "y": 64, "fontSize": 24, "fontWeight": "900", "fill": "#ffd100", "align": "center"}
- ]'::jsonb
-),
-(
- 'Percentuálna zľava (Kruh)',
- '',
- '[
- {"id": "l1", "type": "text", "text": "ZĽAVA", "x": 50, "y": 36, "fontSize": 13, "fontWeight": "800", "fill": "#ffffff", "align": "center"},
- {"id": "l2", "type": "text", "text": "{zlava}%", "x": 50, "y": 68, "fontSize": 24, "fontWeight": "900", "fill": "#ffd100", "align": "center"}
- ]'::jsonb
-)
-ON CONFLICT DO NOTHING;
-
--- 5. Nastavenie RLS (Row Level Security) - pre interný nástroj povolíme verejný prístup cez anon kľúč
-ALTER TABLE templates ENABLE ROW LEVEL SECURITY;
-ALTER TABLE badges ENABLE ROW LEVEL SECURITY;
-ALTER TABLE mapping_presets ENABLE ROW LEVEL SECURITY;
-
-CREATE POLICY "Allow public all on templates" ON templates FOR ALL USING (true) WITH CHECK (true);
-CREATE POLICY "Allow public all on badges" ON badges FOR ALL USING (true) WITH CHECK (true);
-CREATE POLICY "Allow public all on mapping_presets" ON mapping_presets FOR ALL USING (true) WITH CHECK (true);