From 0a5ef715eba73b50613e1c8f85b76eedc83a80f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Ty=C5=84ski?= Date: Sun, 4 Oct 2026 01:24:18 +0200 Subject: [PATCH] feat(sql): add demo schema additions and synthetic seed data Add additive schema for demo (user.display_name, innovation.tags, FLEXIBLE free-form fields) and a fully synthetic seed with organizations, personas, problems, submissions, innovations, knowledge items, grant calls, ideas and tester feedback. Verified on SurrealDB 3.2.4: migrations apply cleanly and are idempotent. --- backend/migrations/0003_demo_schema.surql | 15 +++ backend/migrations/0004_demo_seed.surql | 117 ++++++++++++++++++++++ backend/migrations/README.md | 3 +- 3 files changed, 134 insertions(+), 1 deletion(-) create mode 100644 backend/migrations/0003_demo_schema.surql create mode 100644 backend/migrations/0004_demo_seed.surql diff --git a/backend/migrations/0003_demo_schema.surql b/backend/migrations/0003_demo_schema.surql new file mode 100644 index 0000000..fa52b8b --- /dev/null +++ b/backend/migrations/0003_demo_schema.surql @@ -0,0 +1,15 @@ +-- TarninaHub — migration 0003: additive schema for demo/UI +-- Idempotent, additive. Required before the demo seed (0004). + +-- Human-friendly label for synthetic demo profiles (never personal data). +DEFINE FIELD IF NOT EXISTS display_name ON TABLE user TYPE option; + +-- Innovations are taggable (matchmaking filters), mirroring `problem.tags`. +DEFINE FIELD IF NOT EXISTS tags ON TABLE innovation TYPE array> DEFAULT []; + +-- Free-form payloads must be FLEXIBLE (SCHEMAFULL otherwise rejects nested keys). +DEFINE FIELD OVERWRITE contact ON TABLE organization TYPE option FLEXIBLE; +DEFINE FIELD OVERWRITE content ON TABLE application TYPE object FLEXIBLE DEFAULT {}; +DEFINE FIELD OVERWRITE media ON TABLE innovation TYPE array FLEXIBLE DEFAULT []; +DEFINE FIELD OVERWRITE attachments ON TABLE knowledge_item TYPE array FLEXIBLE DEFAULT []; +DEFINE FIELD OVERWRITE payload ON TABLE notification TYPE object FLEXIBLE DEFAULT {}; diff --git a/backend/migrations/0004_demo_seed.surql b/backend/migrations/0004_demo_seed.surql new file mode 100644 index 0000000..7729bac --- /dev/null +++ b/backend/migrations/0004_demo_seed.surql @@ -0,0 +1,117 @@ +-- TarninaHub — migration 0004: synthetic demo seed (step 09) +-- Idempotent (INSERT IGNORE). ALL DATA IS SYNTHETIC — no real personal or +-- sensitive data. Personas come from the public ROPS Map of Social Challenges +-- and are explicitly synthetic. Phone numbers use the +48 000 reserved range. +-- Passwords are generated demo hashes for a throwaway password. + +-- --------------------------------------------------------------------------- +-- Organizations +-- --------------------------------------------------------------------------- + +INSERT IGNORE INTO organization [ + { id: organization:ngo_dobry_sasiad, name: 'Stowarzyszenie Dobry Sąsiad (demo)', type: 'ngo', location: location:krakow, contact: { email: 'kontakt@example.test' } }, + { id: organization:mops_krakow, name: 'MOPS Kraków (demo)', type: 'jst', location: location:krakow, contact: { email: 'mops@example.test' } }, + { id: organization:instytut_zdrowia, name: 'Instytut Zdrowia Społecznego (demo)', type: 'institution', location: location:krakow, contact: { email: 'instytut@example.test' } }, + { id: organization:firma_care, name: 'CareTech sp. z o.o. (demo)', type: 'company', location: location:tarnow, contact: { email: 'caretech@example.test' } }, + { id: organization:rops_krakow, name: 'ROPS Kraków (demo)', type: 'institution', location: location:krakow, contact: { email: 'rops@example.test' } } +]; + +-- --------------------------------------------------------------------------- +-- Users (synthetic personas + demo staff roles) +-- --------------------------------------------------------------------------- + +INSERT IGNORE INTO user [ + { id: user:ania, display_name: 'Ania (persona)', phone: '+48000000001', email: 'ania@example.test', password: crypto::argon2::generate('Demo1234!'), role: 'user', organization: organization:ngo_dobry_sasiad }, + { id: user:kuba, display_name: 'Kuba (persona)', phone: '+48000000002', email: 'kuba@example.test', password: crypto::argon2::generate('Demo1234!'), role: 'user' }, + { id: user:krystian, display_name: 'Krystian (persona)', phone: '+48000000003', email: 'krystian@example.test', password: crypto::argon2::generate('Demo1234!'), role: 'user' }, + { id: user:tomek, display_name: 'Tomek (persona)', phone: '+48000000004', email: 'tomek@example.test', password: crypto::argon2::generate('Demo1234!'), role: 'user' }, + { id: user:swietlana, display_name: 'Swietłana (persona)', phone: '+48000000005', email: 'swietlana@example.test', password: crypto::argon2::generate('Demo1234!'), role: 'user' }, + { id: user:stanislaw, display_name: 'Stanisław (persona)', phone: '+48000000006', email: 'stanislaw@example.test', password: crypto::argon2::generate('Demo1234!'), role: 'user' }, + { id: user:mateusz, display_name: 'Mateusz (persona)', phone: '+48000000007', email: 'mateusz@example.test', password: crypto::argon2::generate('Demo1234!'), role: 'user' }, + { id: user:karina, display_name: 'Karina (persona)', phone: '+48000000008', email: 'karina@example.test', password: crypto::argon2::generate('Demo1234!'), role: 'user' }, + { id: user:janina, display_name: 'Janina (persona)', phone: '+48000000009', email: 'janina@example.test', password: crypto::argon2::generate('Demo1234!'), role: 'user' }, + { id: user:jst_krakow, display_name: 'Pracownik JST (demo)', phone: '+48000000010', email: 'jst@example.test', password: crypto::argon2::generate('Demo1234!'), role: 'jst', organization: organization:mops_krakow }, + { id: user:rops_operator, display_name: 'Koordynator ROPS (demo)', phone: '+48000000011', email: 'operator@example.test', password: crypto::argon2::generate('Demo1234!'), role: 'operator', organization: organization:rops_krakow }, + { id: user:rops_admin, display_name: 'Administrator ROPS (demo)', phone: '+48000000012', email: 'admin@example.test', password: crypto::argon2::generate('Demo1234!'), role: 'admin', organization: organization:rops_krakow }, + { id: user:ekspert_zdrowie, display_name: 'Ekspert zdrowia (demo)', phone: '+48000000013', email: 'expert@example.test', password: crypto::argon2::generate('Demo1234!'), role: 'manager', organization: organization:instytut_zdrowia } +]; + +-- --------------------------------------------------------------------------- +-- Problems + submissions (matchmaking input, one per challenge) +-- --------------------------------------------------------------------------- + +INSERT IGNORE INTO problem [ + { id: problem:rodzina_rodzenstwo, title: 'Rodzeństwo rozdzielane przy pieczy zastępczej', description: 'Brak miejsc, które pozwalają utrzymać rodzeństwo razem w pieczy rodzinnej.', challenge: social_challenge:rodzina, location: location:krakow, author: user:ania, visibility: 'public', tags: [tag:rodziny, tag:koordynacja_miedzyinstytucjonalna] }, + { id: problem:mloda_bezdomnosc, title: 'Młoda bezdomność bez wsparcia po placówce', description: 'Osoby 18–25 lat po opuszczeniu placówki nie mają oferty wsparcia.', challenge: social_challenge:bezdomnosc, location: location:krakow, author: user:kuba, visibility: 'public', tags: [tag:mlodziez, tag:dostep_do_uslug] }, + { id: problem:praca_on, title: 'Niska aktywność zawodowa osób z niepełnosprawnościami', description: 'Trudność w znalezieniu i utrzymaniu pracy mimo kwalifikacji.', challenge: social_challenge:niepelnosprawnosc, location: location:tarnow, author: user:krystian, visibility: 'public', tags: [tag:osoby_z_niepelnosprawnosciami, tag:usluga] }, + { id: problem:ubostwo_energetyczne, title: 'Ubóstwo energetyczne i żywnościowe seniorów', description: 'Starsze osoby ograniczają ogrzewanie i posiłki z powodu kosztów.', challenge: social_challenge:ubostwo, location: location:nowy_sacz, author: user:tomek, visibility: 'public', tags: [tag:seniorzy, tag:dostep_do_uslug] }, + { id: problem:integracja_jezyk, title: 'Bariera językowa w dostępie do usług', description: 'Cudzoziemcy nie znają procedur i potrzebują asysty kulturowej.', challenge: social_challenge:integracja_cudzoziemcow, location: location:krakow, author: user:swietlana, visibility: 'public', tags: [tag:dostep_do_uslug, tag:wykluczenie_cyfrowe] }, + { id: problem:samotnosc_seniorow, title: 'Samotność i izolacja seniorów', description: 'Mieszkańcy 70+ nie mają kontaktu z otoczeniem i dostępu do informacji.', challenge: social_challenge:zdrowie, location: location:krakow, author: user:stanislaw, visibility: 'public', tags: [tag:seniorzy, tag:samotnosc] }, + { id: problem:zdrowie_psychiczne_mlodziez, title: 'Kryzys zdrowia psychicznego wśród młodzieży', description: 'Wzrost zaburzeń i trudny dostęp do wsparcia środowiskowego.', challenge: social_challenge:zdrowie_psychiczne, location: location:krakow, author: user:mateusz, visibility: 'public', tags: [tag:mlodziez, tag:zdrowie_psychiczne] }, + { id: problem:powrot_na_rynek, title: 'Powrót na rynek pracy po kryzysie psychicznym', description: 'Stigma i brak elastycznych form zatrudnienia utrudniają powrót.', challenge: social_challenge:zdrowie_psychiczne, location: location:tarnow, author: user:karina, visibility: 'public', tags: [tag:zdrowie_psychiczne, tag:usluga] } +]; + +INSERT IGNORE INTO submission [ + { id: submission:rodzina_rodzenstwo, problem: problem:rodzina_rodzenstwo, submitted_by: user:ania, status: 'matched', keywords: ['rodzeństwo', 'piecza', 'rodzina'] }, + { id: submission:mloda_bezdomnosc, problem: problem:mloda_bezdomnosc, submitted_by: user:kuba, status: 'triaged', keywords: ['bezdomność', 'młodzież', 'aktywizacja'] }, + { id: submission:praca_on, problem: problem:praca_on, submitted_by: user:krystian, status: 'matched', keywords: ['praca', 'niepełnosprawność', 'edukacja'] }, + { id: submission:ubostwo_energetyczne, problem: problem:ubostwo_energetyczne, submitted_by: user:tomek, status: 'new', keywords: ['ubóstwo', 'seniorzy', 'energia'] }, + { id: submission:integracja_jezyk, problem: problem:integracja_jezyk, submitted_by: user:swietlana, status: 'matched', keywords: ['cudzoziemcy', 'integracja', 'język'] }, + { id: submission:samotnosc_seniorow, problem: problem:samotnosc_seniorow, submitted_by: user:stanislaw, status: 'matched', keywords: ['samotność', 'seniorzy', 'cyfryzacja'] }, + { id: submission:zdrowie_psychiczne_mlodziez, problem: problem:zdrowie_psychiczne_mlodziez, submitted_by: user:mateusz, status: 'matched', keywords: ['zdrowie psychiczne', 'młodzież', 'profilaktyka'] }, + { id: submission:powrot_na_rynek, problem: problem:powrot_na_rynek, submitted_by: user:karina, status: 'in_progress', keywords: ['zdrowie psychiczne', 'praca', 'reintegracja'] } +]; + +-- --------------------------------------------------------------------------- +-- Innovations (catalogue, one or more per challenge) +-- --------------------------------------------------------------------------- + +INSERT IGNORE INTO innovation [ + { id: innovation:rodziny_grupy, title: 'Grupy wsparcia dla rodzin zastępczych', summary: 'Sieć sąsiedzka utrzymująca rodzeństwo razem.', description: 'Lokalne grupy rodzin zastępczych dzielą się opieką i wsparciem, ograniczając rozdzielanie rodzeństwa.', challenge: social_challenge:rodzina, stage: 'pilot', published: true, tags: [tag:rodziny, tag:koordynacja_miedzyinstytucjonalna] }, + { id: innovation:hostel_mlodzi, title: 'Hostel aktywizacyjny dla młodych dorosłych', summary: 'Mieszkanie z programem usamodzielniania.', description: 'Połączenie schronienia i treningu kompetencji społecznych dla osób 18–25 lat.', challenge: social_challenge:bezdomnosc, stage: 'scaling', published: true, tags: [tag:mlodziez, tag:dostep_do_uslug] }, + { id: innovation:praca_wspierana, title: 'Praca wspierana z doradcą zawodowym', summary: 'Model zatrudnienia wspieranego w tandemie z trenerem pracy.', description: 'Trener pracy wspiera zatrudnienie osoby z niepełnosprawnością u lokalnego pracodawcy.', challenge: social_challenge:niepelnosprawnosc, stage: 'service', published: true, tags: [tag:osoby_z_niepelnosprawnosciami, tag:usluga] }, + { id: innovation:spizarnia, title: 'Sąsiedzka spizarnia i wymiana energii', summary: 'Zbiórki żywności i wsparcie kosztów ogrzewania.', description: 'Lokalne spizarnie społeczne i sąsiedzka pomoc w kosztach energii dla seniorów.', challenge: social_challenge:ubostwo, stage: 'pilot', published: true, tags: [tag:seniorzy, tag:dostep_do_uslug] }, + { id: innovation:asysta_cudzoziemcy, title: 'Asysta kulturowa dla cudzoziemców', summary: 'Tłumacz-asystent prowadzący przez procedury.', description: 'Asystent kulturowy pomaga w urzędzie, szkole i służbie zdrowia.', challenge: social_challenge:integracja_cudzoziemcow, stage: 'service', published: true, tags: [tag:dostep_do_uslug, tag:wykluczenie_cyfrowe] }, + { id: innovation:telefon_zaufania_senior, title: 'Telefon i wizyta sąsiedzka dla seniorów', summary: 'Regularny kontakt i pomoc w cyfryzacji.', description: 'Wolontariusze dzwonią i odwiedzają seniorów, ucząc korzystania z usług online.', challenge: social_challenge:zdrowie, stage: 'scaling', published: true, tags: [tag:seniorzy, tag:samotnosc] }, + { id: innovation:mlodzi_glowy_szkola, title: 'Program wsparcia psychicznego w szkołach', summary: 'Warsztaty i grupy rówieśnicze.', description: 'Szkolne grupy wsparcia i warsztaty profilaktyczne dla młodzieży.', challenge: social_challenge:zdrowie_psychiczne, stage: 'pilot', published: true, tags: [tag:mlodziez, tag:zdrowie_psychiczne] }, + { id: innovation:zatrudnienie_elastyczne, title: 'Elastyczne zatrudnienie po kryzysie', summary: 'Stopniowy powrót na rynek pracy.', description: 'Elastyczne formy pracy i wsparcie mentora dla osób po kryzysie psychicznym.', challenge: social_challenge:zdrowie_psychiczne, stage: 'service', published: true, tags: [tag:zdrowie_psychiczne, tag:usluga] } +]; + +-- --------------------------------------------------------------------------- +-- Knowledge base (metadata + public links only, no copied content) +-- --------------------------------------------------------------------------- + +INSERT IGNORE INTO knowledge_item [ + { id: knowledge_item:raport_rodzina, title: 'Piecza zastępcza w Polsce — raport GUS', kind: 'report', challenge: social_challenge:rodzina, source_url: 'https://stat.gov.pl/obszary-tematyczne/dzieci-i-rodzina/dzieci/piecza-zastepcza-w-2023-roku,1,8.html', published: true }, + { id: knowledge_item:raport_bezdomnosc, title: 'Młoda bezdomność — raport Fundacji po DRUGIE', kind: 'report', challenge: social_challenge:bezdomnosc, source_url: 'https://podrugie.pl/wp-content/uploads/2023/04/RAPORT-DODAJ-MNIE.pdf', published: true }, + { id: knowledge_item:raport_on, title: 'Badanie potrzeb osób niepełnosprawnych — PFRON 2024', kind: 'report', challenge: social_challenge:niepelnosprawnosc, source_url: 'https://www.pfron.org.pl/instytucje/badania-i-analizy-naukowe/raport-koncowy-z-badania-potrzeb-osob-niepelnosprawnych/', published: true }, + { id: knowledge_item:raport_ubostwo, title: 'Poverty Watch — EAPN Polska', kind: 'report', challenge: social_challenge:ubostwo, source_url: 'https://www.eapn.org.pl/eapn/uploads/2023/10/poverty_watch_23_v12_10_v2_ost.pdf', published: true }, + { id: knowledge_item:mapa_wyzwan, title: 'Mapa Wyzwań Społecznych — ROPS Kraków', kind: 'map', challenge: social_challenge:integracja_cudzoziemcow, source_url: 'https://rops.krakow.pl/mpliki/IS/IWS_20/za._nr_2._Mapa_Wyzwa_Spoecznych.pdf', published: true }, + { id: knowledge_item:raport_samotnosc, title: 'Raport o samotności — Szlachetna Paczka', kind: 'report', challenge: social_challenge:zdrowie, source_url: 'https://www.szlachetnapaczka.pl/wp-content/uploads/2021/03/raport_o_samotnosci_2021.pdf', published: true }, + { id: knowledge_item:raport_mlode_glowy, title: 'Młode Głowy — raport o zdrowiu psychicznym', kind: 'report', challenge: social_challenge:zdrowie_psychiczne, source_url: 'https://mlodeglowy.pl/wp-content/uploads/2023/04/MLODE-GLOWY.-Otwarcie-o-zdrowiu-psychicznym_-Raport-final.pdf', published: true }, + { id: knowledge_item:raport_seniorzy, title: 'Sytuacja osób starszych w Polsce — GUS 2022', kind: 'report', challenge: social_challenge:seniorzy, source_url: 'https://stat.gov.pl/obszary-tematyczne/osoby-starsze/osoby-starsze/sytuacja-osob-starszych-w-polscie-w-2022-roku,2,5.html', published: true } +]; + +-- --------------------------------------------------------------------------- +-- Grant calls + ideas + test feedback +-- --------------------------------------------------------------------------- + +INSERT IGNORE INTO grant_call [ + { id: grant_call:innowacje_2026, name: 'Innowacje społeczne 2026 (demo)', opens_at: d'2026-09-01T00:00:00Z', closes_at: d'2026-12-31T23:59:59Z', status: 'open', external_id: 'DEMO/5.1/2026-01' }, + { id: grant_call:seniorzy_2026, name: 'Włączenie seniorów 2026 (demo)', opens_at: d'2026-10-01T00:00:00Z', closes_at: d'2026-11-30T23:59:59Z', status: 'open', external_id: 'DEMO/5.1/2026-02' } +]; + +INSERT IGNORE INTO idea [ + { id: idea:klub_sasiedzki, title: 'Klub sąsiedzki dla seniorów', description: 'Miejsce spotkań i nauki cyfrowej dla osób starszych.', author: user:janina, status: 'submitted' }, + { id: idea:rower_terapeutyczny, title: 'Rower cargo dla wsparcia psychicznego', description: 'Wspólne wyjazdy jako forma terapii młodzieży.', author: user:mateusz, status: 'in_review' }, + { id: idea:doradca_online, title: 'Doradca online dla osób z niepełnosprawnościami', description: 'Zdalne wsparcie w szukaniu pracy.', author: user:krystian, status: 'draft' } +]; + +INSERT IGNORE INTO application [ + { id: application:klub_sasiedzki, grant_call: grant_call:seniorzy_2026, idea: idea:klub_sasiedzki, content: { budget: 'syntetyczny', scope: 'klub sąsiedzki' }, status: 'submitted' } +]; + +INSERT IGNORE INTO test_feedback [ + { id: test_feedback:grupy_rodzinne_1, innovation: innovation:rodziny_grupy, author: user:ania, rating: 5, comment: 'Model dobrze łączy rodziny.', improvements: 'Potrzebna koordynacja powiatowa.' }, + { id: test_feedback:mlodzi_glowy_1, innovation: innovation:mlodzi_glowy_szkola, author: user:karina, rating: 4, comment: 'Warsztaty potrzebne i trafne.', improvements: 'Zwiększyć liczbę grup rówieśniczych.' } +]; diff --git a/backend/migrations/README.md b/backend/migrations/README.md index 97e9afd..342ca03 100644 --- a/backend/migrations/README.md +++ b/backend/migrations/README.md @@ -8,7 +8,8 @@ Migracje w SurrealQL, wersjonowane w git. Backend (plik/RocksDB) jest źródłem |---|---| | `0001_schema.surql` | tabele, pola, indeksy (w tym HNSW + pełnotekstowy), `ACCESS`, `PERMISSIONS`, `ASSERT` | | `0002_taxonomy_seed.surql` | 8 obszarów (`social_challenge`), tagi, próbka lokalizacji | -| `0003_demo_seed.surql` | dane syntetyczne (dodawane w kroku 09) | +| `0003_demo_schema.surql` | dodatki schematu pod demo: `user.display_name`, `innovation.tags`, pola `FLEXIBLE` | +| `0004_demo_seed.surql` | dane syntetyczne (persony, problemy, innowacje, wiedza, nabory) | ## Zasady