[{"data":1,"prerenderedAt":2192},["ShallowReactive",2],{"navigation_docs_hu":3,"-hu-notify-overview":442,"-hu-notify-overview-surround":2187},[4,45,60,81,112,129,146,173,197,213,242,280,357,373,385,404,430],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":44},"Kezdő lépések","i-lucide-rocket","\u002Fhu\u002Fgetting-started","hu\u002F1.getting-started",[10,15,20,24,29,34,39],{"title":11,"path":12,"stem":13,"icon":14},"Bevezetés","\u002Fhu\u002Fgetting-started\u002Fintroduction","hu\u002F1.getting-started\u002F1.introduction","i-lucide-house",{"title":16,"path":17,"stem":18,"icon":19},"Laravelből érkezőknek","\u002Fhu\u002Fgetting-started\u002Fcoming-from-laravel","hu\u002F1.getting-started\u002F2.coming-from-laravel","i-lucide-arrow-right-left",{"title":21,"path":22,"stem":23,"icon":19},"Symfonyból érkezőknek","\u002Fhu\u002Fgetting-started\u002Fcoming-from-symfony","hu\u002F1.getting-started\u002F3.coming-from-symfony",{"title":25,"path":26,"stem":27,"icon":28},"Telepítés","\u002Fhu\u002Fgetting-started\u002Finstallation","hu\u002F1.getting-started\u002F4.installation","i-lucide-download",{"title":30,"path":31,"stem":32,"icon":33},"Az első modulod","\u002Fhu\u002Fgetting-started\u002Ffirst-module","hu\u002F1.getting-started\u002F5.first-module","i-lucide-package-plus",{"title":35,"path":36,"stem":37,"icon":38},"Projektstruktúra","\u002Fhu\u002Fgetting-started\u002Fproject-structure","hu\u002F1.getting-started\u002F6.project-structure","i-lucide-folder-tree",{"title":40,"path":41,"stem":42,"icon":43},"A shop mintaalkalmazás","\u002Fhu\u002Fgetting-started\u002Fsample-app","hu\u002F1.getting-started\u002F7.sample-app","i-lucide-shopping-cart",false,{"title":46,"icon":47,"path":48,"stem":49,"children":50,"page":44},"queue","i-lucide-layers","\u002Fhu\u002Fqueue","hu\u002F10.queue",[51,56],{"title":52,"path":53,"stem":54,"icon":55},"Áttekintés","\u002Fhu\u002Fqueue\u002Foverview","hu\u002F10.queue\u002F1.overview","i-lucide-list-ordered",{"title":57,"path":58,"stem":59,"icon":47},"Taskok","\u002Fhu\u002Fqueue\u002Ftasks","hu\u002F10.queue\u002F2.tasks",{"title":61,"icon":62,"path":63,"stem":64,"children":65,"page":44},"events","i-lucide-workflow","\u002Fhu\u002Fevents","hu\u002F11.events",[66,71,76],{"title":67,"path":68,"stem":69,"icon":70},"Események","\u002Fhu\u002Fevents\u002Foverview","hu\u002F11.events\u002F1.overview","i-lucide-radio",{"title":72,"path":73,"stem":74,"icon":75},"Outbox","\u002Fhu\u002Fevents\u002Foutbox","hu\u002F11.events\u002F2.outbox","i-lucide-inbox",{"title":77,"path":78,"stem":79,"icon":80},"Ütemezés","\u002Fhu\u002Fevents\u002Fscheduler","hu\u002F11.events\u002F3.scheduler","i-lucide-calendar-clock",{"title":82,"icon":83,"path":84,"stem":85,"children":86,"page":44},"auth","i-lucide-shield-check","\u002Fhu\u002Fauth","hu\u002F12.auth",[87,92,97,102,107],{"title":88,"path":89,"stem":90,"icon":91},"Autentikáció","\u002Fhu\u002Fauth\u002Foverview","hu\u002F12.auth\u002F1.overview","i-lucide-key-round",{"title":93,"path":94,"stem":95,"icon":96},"RBAC","\u002Fhu\u002Fauth\u002Frbac","hu\u002F12.auth\u002F2.rbac","i-lucide-users",{"title":98,"path":99,"stem":100,"icon":101},"Policy-k","\u002Fhu\u002Fauth\u002Fpolicy","hu\u002F12.auth\u002F3.policy","i-lucide-gavel",{"title":103,"path":104,"stem":105,"icon":106},"Az auth önálló használata","\u002Fhu\u002Fauth\u002Fstandalone","hu\u002F12.auth\u002F4.standalone","i-lucide-plug",{"title":108,"path":109,"stem":110,"icon":111},"Social login goth-tal, önállóan","\u002Fhu\u002Fauth\u002Fsocial-standalone","hu\u002F12.auth\u002F5.social-standalone","i-lucide-log-in",{"title":113,"icon":114,"path":115,"stem":116,"children":117,"page":44},"mail","i-lucide-mail","\u002Fhu\u002Fmail","hu\u002F13.mail",[118,121,125],{"title":52,"path":119,"stem":120,"icon":114},"\u002Fhu\u002Fmail\u002Foverview","hu\u002F13.mail\u002F1.overview",{"title":122,"path":123,"stem":124,"icon":114},"SMTP","\u002Fhu\u002Fmail\u002Fsmtp","hu\u002F13.mail\u002F2.smtp",{"title":126,"path":127,"stem":128,"icon":114},"MJML","\u002Fhu\u002Fmail\u002Fmjml","hu\u002F13.mail\u002F3.mjml",{"title":130,"icon":131,"path":132,"stem":133,"children":134,"page":44},"notify","i-lucide-bell","\u002Fhu\u002Fnotify","hu\u002F14.notify",[135,138,142],{"title":52,"path":136,"stem":137,"icon":131},"\u002Fhu\u002Fnotify\u002Foverview","hu\u002F14.notify\u002F1.overview",{"title":139,"path":140,"stem":141,"icon":131},"Database csatorna","\u002Fhu\u002Fnotify\u002Fdatabase","hu\u002F14.notify\u002F2.database",{"title":143,"path":144,"stem":145,"icon":131},"Broadcast csatorna","\u002Fhu\u002Fnotify\u002Fbroadcast","hu\u002F14.notify\u002F3.broadcast",{"title":147,"icon":148,"path":149,"stem":150,"children":151,"page":44},"storage","i-lucide-hard-drive","\u002Fhu\u002Fstorage","hu\u002F15.storage",[152,155,159,163,168],{"title":52,"path":153,"stem":154,"icon":148},"\u002Fhu\u002Fstorage\u002Foverview","hu\u002F15.storage\u002F1.overview",{"title":156,"path":157,"stem":158},"Disk API","\u002Fhu\u002Fstorage\u002Fdisk-api","hu\u002F15.storage\u002F2.disk-api",{"title":160,"path":161,"stem":162,"icon":148},"Memória és helyi lemez","\u002Fhu\u002Fstorage\u002Flocal","hu\u002F15.storage\u002F3.local",{"title":164,"path":165,"stem":166,"icon":167},"S3","\u002Fhu\u002Fstorage\u002Fs3","hu\u002F15.storage\u002F4.s3","i-lucide-cloud",{"title":169,"path":170,"stem":171,"icon":172},"Tesztelés","\u002Fhu\u002Fstorage\u002Ftesting","hu\u002F15.storage\u002F5.testing","i-lucide-flask-conical",{"title":174,"icon":175,"path":176,"stem":177,"children":178,"page":44},"telemetry","i-lucide-activity","\u002Fhu\u002Ftelemetry","hu\u002F16.telemetry",[179,182,187,192],{"title":52,"path":180,"stem":181,"icon":175},"\u002Fhu\u002Ftelemetry\u002Foverview","hu\u002F16.telemetry\u002F1.overview",{"title":183,"path":184,"stem":185,"icon":186},"Logolás","\u002Fhu\u002Ftelemetry\u002Flogging","hu\u002F16.telemetry\u002F2.logging","i-lucide-scroll-text",{"title":188,"path":189,"stem":190,"icon":191},"OpenTelemetry","\u002Fhu\u002Ftelemetry\u002Fopentelemetry","hu\u002F16.telemetry\u002F3.opentelemetry","i-lucide-radar",{"title":193,"path":194,"stem":195,"icon":196},"Sentry","\u002Fhu\u002Ftelemetry\u002Fsentry","hu\u002F16.telemetry\u002F4.sentry","i-lucide-bug",{"title":198,"icon":199,"path":200,"stem":201,"children":202,"page":44},"Referencia","i-lucide-book-open","\u002Fhu\u002Freference","hu\u002F17.reference",[203,208],{"title":204,"path":205,"stem":206,"icon":207},"Konfiguráció","\u002Fhu\u002Freference\u002Fconfiguration","hu\u002F17.reference\u002F1.configuration","i-lucide-settings",{"title":209,"path":210,"stem":211,"icon":212},"Külső függőségek","\u002Fhu\u002Freference\u002Fdependencies","hu\u002F17.reference\u002F2.dependencies","i-lucide-package",{"title":214,"icon":215,"path":216,"stem":217,"children":218,"page":44},"Koncepciók","i-lucide-lightbulb","\u002Fhu\u002Fconcepts","hu\u002F2.concepts",[219,223,228,232,237],{"title":220,"path":221,"stem":222,"icon":47},"Architektúra","\u002Fhu\u002Fconcepts\u002Farchitecture","hu\u002F2.concepts\u002F1.architecture",{"title":224,"path":225,"stem":226,"icon":227},"Hibamodell","\u002Fhu\u002Fconcepts\u002Ferror-model","hu\u002F2.concepts\u002F2.error-model","i-lucide-shield-alert",{"title":204,"path":229,"stem":230,"icon":231},"\u002Fhu\u002Fconcepts\u002Fconfiguration","hu\u002F2.concepts\u002F3.configuration","i-lucide-settings-2",{"title":233,"path":234,"stem":235,"icon":236},"Codegen pipeline","\u002Fhu\u002Fconcepts\u002Fcodegen-pipeline","hu\u002F2.concepts\u002F4.codegen-pipeline","i-lucide-file-json",{"title":238,"path":239,"stem":240,"icon":241},"Design patternek","\u002Fhu\u002Fconcepts\u002Fdesign-patterns","hu\u002F2.concepts\u002F5.design-patterns","i-lucide-puzzle",{"title":243,"icon":244,"path":245,"stem":246,"children":247,"page":44},"A kit","i-lucide-box","\u002Fhu\u002Fkit","hu\u002F3.kit",[248,252,257,262,267,271,276],{"title":249,"path":250,"stem":251,"icon":244},"A kit áttekintése","\u002Fhu\u002Fkit\u002Foverview","hu\u002F3.kit\u002F1.overview",{"title":253,"path":254,"stem":255,"icon":256},"Alkalmazás-életciklus","\u002Fhu\u002Fkit\u002Fapp","hu\u002F3.kit\u002F2.app","i-lucide-power",{"title":258,"path":259,"stem":260,"icon":261},"Szerver","\u002Fhu\u002Fkit\u002Fserver","hu\u002F3.kit\u002F3.server","i-lucide-server",{"title":263,"path":264,"stem":265,"icon":266},"Worker","\u002Fhu\u002Fkit\u002Fworker","hu\u002F3.kit\u002F4.worker","i-lucide-cog",{"title":268,"path":269,"stem":270,"icon":70},"Realtime","\u002Fhu\u002Fkit\u002Frealtime","hu\u002F3.kit\u002F5.realtime",{"title":272,"path":273,"stem":274,"icon":275},"Migrációk","\u002Fhu\u002Fkit\u002Fmigrations","hu\u002F3.kit\u002F6.migrations","i-lucide-file-stack",{"title":277,"path":278,"stem":279,"icon":111},"Social login","\u002Fhu\u002Fkit\u002Fsocial-login","hu\u002F3.kit\u002F7.social-login",{"title":281,"icon":282,"path":283,"stem":284,"children":285,"page":44},"CLI referencia","i-lucide-terminal","\u002Fhu\u002Fcli","hu\u002F4.cli",[286,289,294,299,304,309,314,319,324,329,334,338,343,348,352],{"title":52,"path":287,"stem":288,"icon":282},"\u002Fhu\u002Fcli\u002Foverview","hu\u002F4.cli\u002F1.overview",{"title":290,"path":291,"stem":292,"icon":293},"add db","\u002Fhu\u002Fcli\u002Fadd-db","hu\u002F4.cli\u002F10.add-db","i-lucide-database-zap",{"title":295,"path":296,"stem":297,"icon":298},"add compose \u002F add docker","\u002Fhu\u002Fcli\u002Fadd-compose","hu\u002F4.cli\u002F11.add-compose","i-lucide-container",{"title":300,"path":301,"stem":302,"icon":303},"add mail","\u002Fhu\u002Fcli\u002Fadd-mail","hu\u002F4.cli\u002F12.add-mail","i-lucide-mail-plus",{"title":305,"path":306,"stem":307,"icon":308},"add notification","\u002Fhu\u002Fcli\u002Fadd-notification","hu\u002F4.cli\u002F13.add-notification","i-lucide-bell-plus",{"title":310,"path":311,"stem":312,"icon":313},"add realtime","\u002Fhu\u002Fcli\u002Fadd-realtime","hu\u002F4.cli\u002F14.add-realtime","i-lucide-radio-tower",{"title":315,"path":316,"stem":317,"icon":318},"add seeder","\u002Fhu\u002Fcli\u002Fadd-seeder","hu\u002F4.cli\u002F15.add-seeder","i-lucide-sprout",{"title":320,"path":321,"stem":322,"icon":323},"new project","\u002Fhu\u002Fcli\u002Fnew-project","hu\u002F4.cli\u002F2.new-project","i-lucide-folder-plus",{"title":325,"path":326,"stem":327,"icon":328},"new module","\u002Fhu\u002Fcli\u002Fnew-module","hu\u002F4.cli\u002F3.new-module","i-lucide-blocks",{"title":330,"path":331,"stem":332,"icon":333},"add surface","\u002Fhu\u002Fcli\u002Fadd-surface","hu\u002F4.cli\u002F4.add-surface","i-lucide-layers-2",{"title":335,"path":336,"stem":337,"icon":244},"add core","\u002Fhu\u002Fcli\u002Fadd-core","hu\u002F4.cli\u002F5.add-core",{"title":339,"path":340,"stem":341,"icon":342},"add handler","\u002Fhu\u002Fcli\u002Fadd-handler","hu\u002F4.cli\u002F6.add-handler","i-lucide-webhook",{"title":344,"path":345,"stem":346,"icon":347},"new migration","\u002Fhu\u002Fcli\u002Fnew-migration","hu\u002F4.cli\u002F7.new-migration","i-lucide-file-plus",{"title":349,"path":350,"stem":351,"icon":266},"worker generátorok","\u002Fhu\u002Fcli\u002Fworker-generators","hu\u002F4.cli\u002F8.worker-generators",{"title":353,"path":354,"stem":355,"icon":356},"upgrade templates","\u002Fhu\u002Fcli\u002Fupgrade-templates","hu\u002F4.cli\u002F9.upgrade-templates","i-lucide-refresh-cw",{"title":358,"icon":227,"path":359,"stem":360,"children":361,"page":44},"errs","\u002Fhu\u002Ferrs","hu\u002F5.errs",[362,365,369],{"title":52,"path":363,"stem":364,"icon":227},"\u002Fhu\u002Ferrs\u002Foverview","hu\u002F5.errs\u002F1.overview",{"title":366,"path":367,"stem":368},"API","\u002Fhu\u002Ferrs\u002Fapi","hu\u002F5.errs\u002F2.api",{"title":370,"path":371,"stem":372,"icon":227},"Integráció","\u002Fhu\u002Ferrs\u002Fintegration","hu\u002F5.errs\u002F3.integration",{"title":374,"icon":231,"path":375,"stem":376,"children":377,"page":44},"envconf","\u002Fhu\u002Fenvconf","hu\u002F6.envconf",[378,381],{"title":52,"path":379,"stem":380,"icon":231},"\u002Fhu\u002Fenvconf\u002Foverview","hu\u002F6.envconf\u002F1.overview",{"title":382,"path":383,"stem":384},"Receptek","\u002Fhu\u002Fenvconf\u002Frecipes","hu\u002F6.envconf\u002F2.recipes",{"title":386,"icon":387,"path":388,"stem":389,"children":390,"page":44},"httperr","i-lucide-globe","\u002Fhu\u002Fhttperr","hu\u002F7.httperr",[391,394,399],{"title":52,"path":392,"stem":393,"icon":387},"\u002Fhu\u002Fhttperr\u002Foverview","hu\u002F7.httperr\u002F1.overview",{"title":395,"path":396,"stem":397,"icon":398},"Hibaválaszok","\u002Fhu\u002Fhttperr\u002Ferror-responses","hu\u002F7.httperr\u002F2.error-responses","i-lucide-octagon-alert",{"title":400,"path":401,"stem":402,"icon":403},"Validáció","\u002Fhu\u002Fhttperr\u002Fvalidation","hu\u002F7.httperr\u002F3.validation","i-lucide-badge-check",{"title":405,"icon":406,"path":407,"stem":408,"children":409,"page":44},"dbx","i-lucide-database","\u002Fhu\u002Fdbx","hu\u002F8.dbx",[410,413,417,421,426],{"title":52,"path":411,"stem":412,"icon":406},"\u002Fhu\u002Fdbx\u002Foverview","hu\u002F8.dbx\u002F1.overview",{"title":414,"path":415,"stem":416,"icon":106},"pgx","\u002Fhu\u002Fdbx\u002Fpg","hu\u002F8.dbx\u002F2.pg",{"title":418,"path":419,"stem":420,"icon":47},"bun","\u002Fhu\u002Fdbx\u002Fbunx","hu\u002F8.dbx\u002F3.bunx",{"title":422,"path":423,"stem":424,"icon":425},"Tranzakciók","\u002Fhu\u002Fdbx\u002Ftransactions","hu\u002F8.dbx\u002F4.transactions","i-lucide-git-merge",{"title":427,"path":428,"stem":429,"icon":318},"Seederek","\u002Fhu\u002Fdbx\u002Fseed","hu\u002F8.dbx\u002F5.seed",{"title":431,"icon":55,"path":432,"stem":433,"children":434,"page":44},"paginate","\u002Fhu\u002Fpaginate","hu\u002F9.paginate",[435,438],{"title":52,"path":436,"stem":437,"icon":55},"\u002Fhu\u002Fpaginate\u002Foverview","hu\u002F9.paginate\u002F1.overview",{"title":439,"path":440,"stem":441,"icon":19},"Cursor-lapozás","\u002Fhu\u002Fpaginate\u002Fcursor","hu\u002F9.paginate\u002F2.cursor",{"id":443,"title":52,"body":444,"description":2180,"extension":2181,"links":2182,"meta":2183,"navigation":2184,"path":136,"seo":2185,"stem":137,"__hash__":2186},"docs_hu\u002Fhu\u002F14.notify\u002F1.overview.md",{"type":445,"value":446,"toc":2169},"minimark",[447,461,510,514,553,625,629,644,648,800,818,821,932,952,956,1086,1093,1127,1143,1147,1169,1203,1232,1246,1251,1289,1333,1336,1388,1416,1420,1438,1818,2128,2136,2140,2165],[448,449,450,451,455,456,460],"p",{},"Egy notification egy ",[452,453,454],"em",{},"recipienthez"," (egy userhez, nem csak egy e-mail címhez) címzett tartalom, ami több csatornán is kimehet: perzisztálva egy database-inboxba, elküldve mailben, élőben kipusholva a ",[457,458,459],"a",{"href":269},"realtime gatewayen"," keresztül. Hogy melyik csatorna sül el, az teljesen attól függ, mit deklarál maga a notification.",[448,462,463,464,467,468,471,472,471,475,478,479,483,484,488,489,493,494,498,499,502,503,506,507,509],{},"A ",[465,466,130],"code",{}," önálló Go modul (",[465,469,470],{},"github.com\u002Fgp-system\u002Fnotify",", +",[465,473,474],{},"notify\u002Fdatabase",[465,476,477],{},"notify\u002Fbroadcast","). A mail-csatornához a ",[457,480,481],{"href":119},[465,482,113],{},"-ra épül, a database-csatornához a ",[457,485,486],{"href":411},[465,487,405],{},"-ra, de szándékosan ",[490,491,492],"strong",{},"nem"," függ a ",[457,495,496],{"href":53},[465,497,46],{},"-tól: a broadcast fire-and-forget pub\u002Fsub, a durable database-csatorna pedig egy sima insert, így itt semmi nem igényel durable job-queue-t. Az aszinkron kézbesítés, ha kell, egy ",[457,500,501],{"href":68},"event"," dispatchálásából és a ",[465,504,505],{},"Hub.Send"," egy listenerből való hívásából jön, ugyanúgy, mint a ",[465,508,113],{},"-nél.",[511,512,25],"h2",{"id":513},"telepítés",[515,516,521],"pre",{"className":517,"code":518,"language":519,"meta":520,"style":520},"language-sh shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","go get github.com\u002Fgp-system\u002Fnotify@v0.1.0 # a kit is ezt a taget használja\ngo get github.com\u002Fgp-system\u002Fnotify@latest\n","sh","",[465,522,523,543],{"__ignoreMap":520},[524,525,528,532,536,539],"span",{"class":526,"line":527},"line",1,[524,529,531],{"class":530},"sBMFI","go",[524,533,535],{"class":534},"sfazB"," get",[524,537,538],{"class":534}," github.com\u002Fgp-system\u002Fnotify@v0.1.0",[524,540,542],{"class":541},"sHwdD"," # a kit is ezt a taget használja\n",[524,544,546,548,550],{"class":526,"line":545},2,[524,547,531],{"class":530},[524,549,535],{"class":534},[524,551,552],{"class":534}," github.com\u002Fgp-system\u002Fnotify@latest\n",[554,555,556,569],"table",{},[557,558,559],"thead",{},[560,561,562,566],"tr",{},[563,564,565],"th",{},"Import-út",[563,567,568],{},"Mit ad hozzá",[570,571,572,594,612],"tbody",{},[560,573,574,579],{},[575,576,577],"td",{},[465,578,470],{},[575,580,581,582,585,586,589,590,593],{},"a ",[465,583,584],{},"Hub","-ot, a ",[465,587,588],{},"Notification","\u002F",[465,591,592],{},"Recipient","-et, a mail-csatornát",[560,595,596,606],{},[575,597,598,601,602,605],{},[465,599,600],{},"github.com\u002Fgp-system\u002Fnotify\u002Fdatabase"," (+",[465,603,604],{},"\u002Fbunx",")",[575,607,608,609],{},"a durable database-csatornát, lásd ",[457,610,611],{"href":140},"Database",[560,613,614,619],{},[575,615,616],{},[465,617,618],{},"github.com\u002Fgp-system\u002Fnotify\u002Fbroadcast",[575,620,621,622],{},"az élő push-csatornát és a gateway építőelemeit, lásd ",[457,623,624],{"href":144},"Broadcast",[511,626,628],{"id":627},"a-harmadik-tudatos-absztrakció","A harmadik tudatos absztrakció",[448,630,463,631,633,634,636,637,639,640,643],{},[457,632,147],{"href":153}," és a ",[457,635,113],{"href":119}," mellett a ",[465,638,130],{}," a kit harmadik tudatos kivétele a ",[457,641,642],{"href":221},"\"centralizálj, ne absztrahálj\""," elv alól: első-party rendszer, ami a termékek gyártását gyorsítja, nem egy 3rd-party API-t elrejtő wrapper. Vékony marad: csatornánként egy type assertion küldésenként, zéró reflection.",[511,645,647],{"id":646},"az-alaptípusok","Az alaptípusok",[515,649,652],{"className":650,"code":651,"language":531,"meta":520,"style":520},"language-go shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import \"github.com\u002Fgp-system\u002Fnotify\"\n\ntype Notification interface {\n    NotificationName() string\n    Via(ctx context.Context, r Recipient) []string\n}\n\ntype Recipient struct {\n    ID    string \u002F\u002F stabil recipient-azonosító (kit-kiadású JWT-kben egy rbac.Identity.Subject)\n    Email string\n    Name  string\n}\n",[465,653,654,669,675,690,704,743,749,754,766,779,787,795],{"__ignoreMap":520},[524,655,656,660,664,666],{"class":526,"line":527},[524,657,659],{"class":658},"s7zQu","import",[524,661,663],{"class":662},"sMK4o"," \"",[524,665,470],{"class":530},[524,667,668],{"class":662},"\"\n",[524,670,671],{"class":526,"line":545},[524,672,674],{"emptyLinePlaceholder":673},true,"\n",[524,676,678,681,684,687],{"class":526,"line":677},3,[524,679,680],{"class":662},"type",[524,682,683],{"class":530}," Notification",[524,685,686],{"class":662}," interface",[524,688,689],{"class":662}," {\n",[524,691,693,697,700],{"class":526,"line":692},4,[524,694,696],{"class":695},"s2Zo4","    NotificationName",[524,698,699],{"class":662},"()",[524,701,703],{"class":702},"spNyl"," string\n",[524,705,707,710,713,717,720,723,726,729,732,735,737,740],{"class":526,"line":706},5,[524,708,709],{"class":695},"    Via",[524,711,712],{"class":662},"(",[524,714,716],{"class":715},"sHdIc","ctx",[524,718,719],{"class":530}," context",[524,721,722],{"class":662},".",[524,724,725],{"class":530},"Context",[524,727,728],{"class":662},",",[524,730,731],{"class":715}," r",[524,733,734],{"class":530}," Recipient",[524,736,605],{"class":662},[524,738,739],{"class":662}," []",[524,741,742],{"class":702},"string\n",[524,744,746],{"class":526,"line":745},6,[524,747,748],{"class":662},"}\n",[524,750,752],{"class":526,"line":751},7,[524,753,674],{"emptyLinePlaceholder":673},[524,755,757,759,761,764],{"class":526,"line":756},8,[524,758,680],{"class":662},[524,760,734],{"class":530},[524,762,763],{"class":662}," struct",[524,765,689],{"class":662},[524,767,769,773,776],{"class":526,"line":768},9,[524,770,772],{"class":771},"sTEyZ","    ID    ",[524,774,775],{"class":702},"string",[524,777,778],{"class":541}," \u002F\u002F stabil recipient-azonosító (kit-kiadású JWT-kben egy rbac.Identity.Subject)\n",[524,780,782,785],{"class":526,"line":781},10,[524,783,784],{"class":771},"    Email ",[524,786,742],{"class":702},[524,788,790,793],{"class":526,"line":789},11,[524,791,792],{"class":771},"    Name  ",[524,794,742],{"class":702},[524,796,798],{"class":526,"line":797},12,[524,799,748],{"class":662},[448,801,463,802,805,806,809,810,813,814,817],{},[465,803,804],{},"NotificationName"," egy stabil, pontozott azonosító (",[465,807,808],{},"\"contact.admin_notification\"","): a database csatorna ezt perzisztálja, span-ek és logok ezt hordozzák, ugyanaz a konvenció mint az ",[465,811,812],{},"events.Event.EventName","-nél. A ",[465,815,816],{},"Via","-t küldésenként kiértékeljük, így ugyanaz a notification-típus recipiensenként másképp routolhat, pl. csak database, ha a recipiensnek nincs regisztrált e-mail címe.",[448,819,820],{},"A csatornánkénti tartalom egy külön, opcionális interfész, amit a csatorna type-asserttel keres:",[515,822,824],{"className":650,"code":823,"language":531,"meta":520,"style":520},"type Mailable interface {\n    ToMail(ctx context.Context, r Recipient) (*mail.Message, error)\n}\ntype Databasable interface {\n    ToDatabase(ctx context.Context, r Recipient) (any, error)\n}\n",[465,825,826,837,878,882,893,928],{"__ignoreMap":520},[524,827,828,830,833,835],{"class":526,"line":527},[524,829,680],{"class":662},[524,831,832],{"class":530}," Mailable",[524,834,686],{"class":662},[524,836,689],{"class":662},[524,838,839,842,844,846,848,850,852,854,856,858,860,863,865,867,870,872,875],{"class":526,"line":545},[524,840,841],{"class":695},"    ToMail",[524,843,712],{"class":662},[524,845,716],{"class":715},[524,847,719],{"class":530},[524,849,722],{"class":662},[524,851,725],{"class":530},[524,853,728],{"class":662},[524,855,731],{"class":715},[524,857,734],{"class":530},[524,859,605],{"class":662},[524,861,862],{"class":662}," (*",[524,864,113],{"class":530},[524,866,722],{"class":662},[524,868,869],{"class":530},"Message",[524,871,728],{"class":662},[524,873,874],{"class":702}," error",[524,876,877],{"class":662},")\n",[524,879,880],{"class":526,"line":677},[524,881,748],{"class":662},[524,883,884,886,889,891],{"class":526,"line":692},[524,885,680],{"class":662},[524,887,888],{"class":530}," Databasable",[524,890,686],{"class":662},[524,892,689],{"class":662},[524,894,895,898,900,902,904,906,908,910,912,914,916,919,922,924,926],{"class":526,"line":706},[524,896,897],{"class":695},"    ToDatabase",[524,899,712],{"class":662},[524,901,716],{"class":715},[524,903,719],{"class":530},[524,905,722],{"class":662},[524,907,725],{"class":530},[524,909,728],{"class":662},[524,911,731],{"class":715},[524,913,734],{"class":530},[524,915,605],{"class":662},[524,917,918],{"class":662}," (",[524,920,921],{"class":530},"any",[524,923,728],{"class":662},[524,925,874],{"class":702},[524,927,877],{"class":662},[524,929,930],{"class":526,"line":745},[524,931,748],{"class":662},[448,933,934,935,938,939,941,942,944,945,948,949,951],{},"Van egy harmadik is, a ",[465,936,937],{},"Broadcastable",", ezt a ",[457,940,624],{"href":144}," oldal tárgyalja, az őt fogyasztó csatornával együtt. Ha a ",[465,943,816],{}," egy olyan csatornát nevez meg, amihez a notification nem implementálja a tartalom-interfészt, az a csatorna ",[465,946,947],{},"notify.ErrNoContent","-et ad vissza; de megpróbálja (lásd a ",[465,950,505],{},"-et lent), sosem csendben kihagyja.",[511,953,955],{"id":954},"a-hub","A Hub",[515,957,959],{"className":650,"code":958,"language":531,"meta":520,"style":520},"hub := notify.NewHub(\n    notify.NewMailChannel(mailer),\n    notifydatabase.NewChannel(store),\n)\nerr := hub.Send(ctx, notify.Recipient{ID: \"u1\", Email: \"user@example.com\"}, OrderShipped{...})\n",[465,960,961,980,998,1015,1019],{"__ignoreMap":520},[524,962,963,966,969,972,974,977],{"class":526,"line":527},[524,964,965],{"class":771},"hub ",[524,967,968],{"class":662},":=",[524,970,971],{"class":771}," notify",[524,973,722],{"class":662},[524,975,976],{"class":695},"NewHub",[524,978,979],{"class":662},"(\n",[524,981,982,985,987,990,992,995],{"class":526,"line":545},[524,983,984],{"class":771},"    notify",[524,986,722],{"class":662},[524,988,989],{"class":695},"NewMailChannel",[524,991,712],{"class":662},[524,993,994],{"class":771},"mailer",[524,996,997],{"class":662},"),\n",[524,999,1000,1003,1005,1008,1010,1013],{"class":526,"line":677},[524,1001,1002],{"class":771},"    notifydatabase",[524,1004,722],{"class":662},[524,1006,1007],{"class":695},"NewChannel",[524,1009,712],{"class":662},[524,1011,1012],{"class":771},"store",[524,1014,997],{"class":662},[524,1016,1017],{"class":526,"line":692},[524,1018,877],{"class":662},[524,1020,1021,1024,1026,1029,1031,1034,1036,1038,1040,1042,1044,1046,1049,1052,1055,1057,1060,1063,1065,1068,1070,1072,1075,1077,1080,1083],{"class":526,"line":706},[524,1022,1023],{"class":771},"err ",[524,1025,968],{"class":662},[524,1027,1028],{"class":771}," hub",[524,1030,722],{"class":662},[524,1032,1033],{"class":695},"Send",[524,1035,712],{"class":662},[524,1037,716],{"class":771},[524,1039,728],{"class":662},[524,1041,971],{"class":530},[524,1043,722],{"class":662},[524,1045,592],{"class":530},[524,1047,1048],{"class":662},"{",[524,1050,1051],{"class":771},"ID",[524,1053,1054],{"class":662},":",[524,1056,663],{"class":662},[524,1058,1059],{"class":534},"u1",[524,1061,1062],{"class":662},"\"",[524,1064,728],{"class":662},[524,1066,1067],{"class":771}," Email",[524,1069,1054],{"class":662},[524,1071,663],{"class":662},[524,1073,1074],{"class":534},"user@example.com",[524,1076,1062],{"class":662},[524,1078,1079],{"class":662},"},",[524,1081,1082],{"class":530}," OrderShipped",[524,1084,1085],{"class":662},"{...})\n",[448,1087,463,1088,1090,1091,1054],{},[465,1089,976],{}," panicol duplikált csatornanévnél: ez boot-idejű drótozási hiba, nem futásidejű állapot. A ",[465,1092,1033],{},[1094,1095,1096,1107,1113,1120],"ol",{},[1097,1098,1099,1100,1102,1103,1106],"li",{},"Egy delivery ID-t stampel a ",[465,1101,716],{},"-be (",[465,1104,1105],{},"notify.IDFromContext","): a database csatorna ezt használja a sor primary key-jeként, a broadcast csatorna envelope-ja ugyanezt az ID-t hordozza, így egy kliens egy élő push-t egy database-sorral tud egyeztetni refetch nélkül.",[1097,1108,1109,1110,1112],{},"Sorban, szinkron, a hívó goroutine-jában megpróbálja mindazt a csatornát, amit a ",[465,1111,816],{}," megnevez.",[1097,1114,1115,1116,1119],{},"Egy nem regisztrált csatornanevet csendben kihagy (discard-szemantika, ugyanaz a \"nincs konfigurálva\" történet, ami az ",[465,1117,1118],{},"smtp.NewIfConfigured","-nál is megvan).",[1097,1121,1122,1123,1126],{},"Minden megnevezett csatornát megpróbál egy korábbi hiba ellenére is; a hibák össze vannak fűzve (",[465,1124,1125],{},"errors.Join","), mindegyik a csatorna és a notification nevével becsomagolva.",[448,1128,1129,1130,1132,1133,1135,1136,1139,1140,1142],{},"Nincs beépített queued mód: a ",[465,1131,130],{}," ugyanazt a szabályt követi, mint a ",[465,1134,113],{},". Aszinkron kézbesítéshez dispatchálj egy ",[457,1137,1138],{"href":68},"eventet"," és hívd a ",[465,1141,505],{},"-et egy listenerből, a meglévő at-least-once retry és idempotencia garanciákkal. Egy listener-redelivery duplikálhat egy database-notificationt; ez egy elfogadott, dokumentált mellékhatás, ugyanaz, amit az eventek is hordoznak.",[511,1144,1146],{"id":1145},"a-mail-csatorna","A mail-csatorna",[515,1148,1150],{"className":650,"code":1149,"language":531,"meta":520,"style":520},"notify.NewMailChannel(mailer) \u002F\u002F mailer: bármilyen mail.Mailer (SMTP, discard, memory)\n",[465,1151,1152],{"__ignoreMap":520},[524,1153,1154,1156,1158,1160,1162,1164,1166],{"class":526,"line":527},[524,1155,130],{"class":771},[524,1157,722],{"class":662},[524,1159,989],{"class":695},[524,1161,712],{"class":662},[524,1163,994],{"class":771},[524,1165,605],{"class":662},[524,1167,1168],{"class":541}," \u002F\u002F mailer: bármilyen mail.Mailer (SMTP, discard, memory)\n",[448,1170,1171,1172,1175,1176,1180,1181,1183,1184,1187,1188,1191,1192,1195,1196,589,1199,1202],{},"Ugyanarra a kit ",[465,1173,1174],{},"mail.Mailer","-re delegál, amit az ",[457,1177,1178],{"href":301},[465,1179,300],{}," drótoz be: egy projekt mail-transzportja közös a direkt ",[465,1182,1174],{},"-küldések és a notificationök között. Ha a ",[465,1185,1186],{},"ToMail"," visszaadott ",[465,1189,1190],{},"*mail.Message","-én nincs ",[465,1193,1194],{},"To"," beállítva, a csatorna automatikusan ",[465,1197,1198],{},"r.Email",[465,1200,1201],{},"r.Name","-re routolja.",[448,1204,1205,1206,1208,1209,1211,1212,1214,1215,1217,1218,1220,1221,589,1224,1227,1228,1231],{},"Az ",[465,1207,300],{}," és az ",[465,1210,305],{}," független és összeadódik: a ",[465,1213,300],{},"-t olyan tartalomhoz használd, ami közvetlenül egy címre megy, recipient-fogalom nélkül (egy contact-form visszaigazolás); az ",[465,1216,305],{},"-t olyan tartalomhoz, ami egy recipiensnek szól, akár több csatornán. Egy notification ",[465,1219,1186],{},"-je ugyanazt a ",[465,1222,1223],{},"mail.Message",[465,1225,1226],{},"mail.Template"," buildert használja, mint egy mail-notifier ",[465,1229,1230],{},"Notify","-ja.",[448,1233,1234,1235,1237,1238,1240,1241,1237,1243,1245],{},"A database-csatornáért (",[465,1236,474],{},") lásd a ",[457,1239,611],{"href":140}," oldalt; a broadcast-csatornáért (",[465,1242,477],{},[457,1244,624],{"href":144}," oldalt.",[511,1247,1249],{"id":1248},"add-notification",[465,1250,305],{},[515,1252,1254],{"className":517,"code":1253,"language":519,"meta":520,"style":520},"gpsystem add notification \u003Cmodule> \u003Cname>\n",[465,1255,1256],{"__ignoreMap":520},[524,1257,1258,1261,1264,1267,1270,1273,1276,1279,1281,1284,1286],{"class":526,"line":527},[524,1259,1260],{"class":530},"gpsystem",[524,1262,1263],{"class":534}," add",[524,1265,1266],{"class":534}," notification",[524,1268,1269],{"class":662}," \u003C",[524,1271,1272],{"class":534},"modul",[524,1274,1275],{"class":771},"e",[524,1277,1278],{"class":662},">",[524,1280,1269],{"class":662},[524,1282,1283],{"class":534},"nam",[524,1285,1275],{"class":771},[524,1287,1288],{"class":662},">\n",[448,1290,1291,1292,1295,1296,1298,1299,1302,1303,1305,1306,589,1308,1310,1311,1314,1315,1318,1319,1322,1323,1326,1327,1332],{},"Generál egy ",[465,1293,1294],{},"internal\u002Fmodules\u002F\u003Cmodule>\u002Fnotifications\u002F\u003Cname>.go","-t: egy üres payload structot, ",[465,1297,816],{},"-t (alapból ",[465,1300,1301],{},"[database, mail]","), egy ",[465,1304,1186],{},"-t a kit ",[465,1307,1223],{},[465,1309,1226],{},"-jére építve, egy ",[465,1312,1313],{},"ToDatabase","-t ami önmagát adja vissza, plusz a ",[465,1316,1317],{},"templates\u002F\u003Cname>.{html,txt}.tmpl"," fájlokat. A projekt első notificationjénél bedrótoz egy közös ",[465,1320,1321],{},"notify.Sender","-t (mail + database csatorna, plusz broadcast, ha a realtime gateway jelen van) minden belépési pontba, és hozzáadja a ",[465,1324,1325],{},"notifications"," tábla migrációt. Lásd az ",[457,1328,1329,1331],{"href":306},[465,1330,305],{}," referenciát"," a pontos generált formáért és a wiring-anchorokért.",[511,1334,169],{"id":1335},"tesztelés",[515,1337,1339],{"className":650,"code":1338,"language":531,"meta":520,"style":520},"mem := notify.NewMemory(notify.ChannelDatabase) \u002F\u002F Deliveries()-t rögzít bármely csatornanévre\nhub := notify.NewHub(mem)\n",[465,1340,1341,1369],{"__ignoreMap":520},[524,1342,1343,1346,1348,1350,1352,1355,1357,1359,1361,1364,1366],{"class":526,"line":527},[524,1344,1345],{"class":771},"mem ",[524,1347,968],{"class":662},[524,1349,971],{"class":771},[524,1351,722],{"class":662},[524,1353,1354],{"class":695},"NewMemory",[524,1356,712],{"class":662},[524,1358,130],{"class":771},[524,1360,722],{"class":662},[524,1362,1363],{"class":771},"ChannelDatabase",[524,1365,605],{"class":662},[524,1367,1368],{"class":541}," \u002F\u002F Deliveries()-t rögzít bármely csatornanévre\n",[524,1370,1371,1373,1375,1377,1379,1381,1383,1386],{"class":526,"line":545},[524,1372,965],{"class":771},[524,1374,968],{"class":662},[524,1376,971],{"class":771},[524,1378,722],{"class":662},[524,1380,976],{"class":695},[524,1382,712],{"class":662},[524,1384,1385],{"class":771},"mem",[524,1387,877],{"class":662},[448,1389,1390,1391,1394,1395,1398,1399,1402,1403,1406,1407,633,1411,1415],{},"Tartalom-renderelési lefedettséghez a valós csatornákat érdemes valós driverek felett használni: ",[465,1392,1393],{},"notify.NewMailChannel(mail.NewMemory())"," és ",[465,1396,1397],{},"notifydatabase.NewChannel(notifydatabase.NewMemoryStore())",": a ",[465,1400,1401],{},"MemoryStore"," a teljes ",[465,1404,1405],{},"Store","-t implementálja (az olvasó oldalt is), így egy termék Postgres nélkül tesztelheti az inbox-handlereit. A csatornánkénti test double-ökért lásd a ",[457,1408,1410],{"href":1409},"\u002Fhu\u002Fnotify\u002Fdatabase#memorystore","Database#memorystore",[457,1412,1414],{"href":1413},"\u002Fhu\u002Fnotify\u002Fbroadcast#memory","Broadcast#memory"," szakaszt.",[511,1417,1419],{"id":1418},"kidolgozott-példa-a-contact-email-flow","Kidolgozott példa: a contact-email flow",[448,1421,463,1422,1426,1427,1430,1431,1434,1435,1437],{},[457,1423,1425],{"href":1424},"\u002Fhu\u002Fmail\u002Foverview#kidolgozott-p%C3%A9lda-a-contact-email-flow","mail oldal kidolgozott példája"," egy contact-form beküldés admin-értesítését és a beküldő visszaigazolását két direkt mailként küldi. Notificationként újragondolva az admin-oldal egy ",[465,1428,1429],{},"notify.Notification"," lesz, az admin fiókhoz címezve (subject ",[465,1432,1433],{},"\"admin\""," egy single-admin projektben), kézbesítve mind a database csatornán (perzisztált admin-inbox), mind a mail csatornán (ugyanarra a címre, mint a direkt küldés); míg a beküldő visszaigazolása, aminek nincs recipient-fogalma a form e-mail címén túl, marad egy direkt ",[465,1436,1174],{},"-küldés:",[515,1439,1442],{"className":650,"code":1440,"filename":1441,"language":531,"meta":520,"style":520},"package notifications\n\ntype AdminNotification struct {\n    contactmail.ContactNotification \u002F\u002F ugyanaz a payload, amit a beküldőmail renderel\n}\n\nfunc (AdminNotification) NotificationName() string { return \"contact.admin_notification\" }\n\nfunc (AdminNotification) Via(context.Context, notify.Recipient) []string {\n    return []string{notify.ChannelDatabase, notify.ChannelMail}\n}\n\nfunc (n AdminNotification) ToMail(context.Context, notify.Recipient) (*kitmail.Message, error) {\n    return kitmail.NewMessage().\n        WithSubject(adminSubjectLine(n.ContactNotification)).\n        WithBody(kitmail.Template(templatesFS, \"templates\u002Fadminnotification.html.tmpl\", n).\n            WithTextTemplate(\"templates\u002Fadminnotification.txt.tmpl\")), nil\n}\n\nfunc (n AdminNotification) ToDatabase(context.Context, notify.Recipient) (any, error) { return n, nil }\n","internal\u002Fmodules\u002Fcontact\u002Fnotifications\u002Fadminnotification.go",[465,1443,1444,1452,1456,1467,1480,1484,1488,1524,1528,1566,1594,1598,1602,1654,1670,1693,1730,1751,1756,1761],{"__ignoreMap":520},[524,1445,1446,1449],{"class":526,"line":527},[524,1447,1448],{"class":662},"package",[524,1450,1451],{"class":530}," notifications\n",[524,1453,1454],{"class":526,"line":545},[524,1455,674],{"emptyLinePlaceholder":673},[524,1457,1458,1460,1463,1465],{"class":526,"line":677},[524,1459,680],{"class":662},[524,1461,1462],{"class":530}," AdminNotification",[524,1464,763],{"class":662},[524,1466,689],{"class":662},[524,1468,1469,1472,1474,1477],{"class":526,"line":692},[524,1470,1471],{"class":530},"    contactmail",[524,1473,722],{"class":662},[524,1475,1476],{"class":530},"ContactNotification",[524,1478,1479],{"class":541}," \u002F\u002F ugyanaz a payload, amit a beküldőmail renderel\n",[524,1481,1482],{"class":526,"line":706},[524,1483,748],{"class":662},[524,1485,1486],{"class":526,"line":745},[524,1487,674],{"emptyLinePlaceholder":673},[524,1489,1490,1493,1495,1498,1500,1503,1505,1508,1511,1514,1516,1519,1521],{"class":526,"line":751},[524,1491,1492],{"class":662},"func",[524,1494,918],{"class":662},[524,1496,1497],{"class":530},"AdminNotification",[524,1499,605],{"class":662},[524,1501,1502],{"class":695}," NotificationName",[524,1504,699],{"class":662},[524,1506,1507],{"class":702}," string",[524,1509,1510],{"class":662}," {",[524,1512,1513],{"class":658}," return",[524,1515,663],{"class":662},[524,1517,1518],{"class":534},"contact.admin_notification",[524,1520,1062],{"class":662},[524,1522,1523],{"class":662}," }\n",[524,1525,1526],{"class":526,"line":756},[524,1527,674],{"emptyLinePlaceholder":673},[524,1529,1530,1532,1534,1536,1538,1541,1543,1546,1548,1550,1552,1554,1556,1558,1560,1562,1564],{"class":526,"line":768},[524,1531,1492],{"class":662},[524,1533,918],{"class":662},[524,1535,1497],{"class":530},[524,1537,605],{"class":662},[524,1539,1540],{"class":695}," Via",[524,1542,712],{"class":662},[524,1544,1545],{"class":530},"context",[524,1547,722],{"class":662},[524,1549,725],{"class":530},[524,1551,728],{"class":662},[524,1553,971],{"class":530},[524,1555,722],{"class":662},[524,1557,592],{"class":530},[524,1559,605],{"class":662},[524,1561,739],{"class":662},[524,1563,775],{"class":702},[524,1565,689],{"class":662},[524,1567,1568,1571,1573,1575,1577,1579,1581,1583,1585,1587,1589,1592],{"class":526,"line":781},[524,1569,1570],{"class":658},"    return",[524,1572,739],{"class":662},[524,1574,775],{"class":702},[524,1576,1048],{"class":662},[524,1578,130],{"class":771},[524,1580,722],{"class":662},[524,1582,1363],{"class":771},[524,1584,728],{"class":662},[524,1586,971],{"class":771},[524,1588,722],{"class":662},[524,1590,1591],{"class":771},"ChannelMail",[524,1593,748],{"class":662},[524,1595,1596],{"class":526,"line":789},[524,1597,748],{"class":662},[524,1599,1600],{"class":526,"line":797},[524,1601,674],{"emptyLinePlaceholder":673},[524,1603,1605,1607,1609,1612,1614,1616,1619,1621,1623,1625,1627,1629,1631,1633,1635,1637,1639,1642,1644,1646,1648,1650,1652],{"class":526,"line":1604},13,[524,1606,1492],{"class":662},[524,1608,918],{"class":662},[524,1610,1611],{"class":715},"n ",[524,1613,1497],{"class":530},[524,1615,605],{"class":662},[524,1617,1618],{"class":695}," ToMail",[524,1620,712],{"class":662},[524,1622,1545],{"class":530},[524,1624,722],{"class":662},[524,1626,725],{"class":530},[524,1628,728],{"class":662},[524,1630,971],{"class":530},[524,1632,722],{"class":662},[524,1634,592],{"class":530},[524,1636,605],{"class":662},[524,1638,862],{"class":662},[524,1640,1641],{"class":530},"kitmail",[524,1643,722],{"class":662},[524,1645,869],{"class":530},[524,1647,728],{"class":662},[524,1649,874],{"class":702},[524,1651,605],{"class":662},[524,1653,689],{"class":662},[524,1655,1657,1659,1662,1664,1667],{"class":526,"line":1656},14,[524,1658,1570],{"class":658},[524,1660,1661],{"class":771}," kitmail",[524,1663,722],{"class":662},[524,1665,1666],{"class":695},"NewMessage",[524,1668,1669],{"class":662},"().\n",[524,1671,1673,1676,1678,1681,1683,1686,1688,1690],{"class":526,"line":1672},15,[524,1674,1675],{"class":695},"        WithSubject",[524,1677,712],{"class":662},[524,1679,1680],{"class":695},"adminSubjectLine",[524,1682,712],{"class":662},[524,1684,1685],{"class":771},"n",[524,1687,722],{"class":662},[524,1689,1476],{"class":771},[524,1691,1692],{"class":662},")).\n",[524,1694,1696,1699,1701,1703,1705,1708,1710,1713,1715,1717,1720,1722,1724,1727],{"class":526,"line":1695},16,[524,1697,1698],{"class":695},"        WithBody",[524,1700,712],{"class":662},[524,1702,1641],{"class":771},[524,1704,722],{"class":662},[524,1706,1707],{"class":695},"Template",[524,1709,712],{"class":662},[524,1711,1712],{"class":771},"templatesFS",[524,1714,728],{"class":662},[524,1716,663],{"class":662},[524,1718,1719],{"class":534},"templates\u002Fadminnotification.html.tmpl",[524,1721,1062],{"class":662},[524,1723,728],{"class":662},[524,1725,1726],{"class":771}," n",[524,1728,1729],{"class":662},").\n",[524,1731,1733,1736,1738,1740,1743,1745,1748],{"class":526,"line":1732},17,[524,1734,1735],{"class":695},"            WithTextTemplate",[524,1737,712],{"class":662},[524,1739,1062],{"class":662},[524,1741,1742],{"class":534},"templates\u002Fadminnotification.txt.tmpl",[524,1744,1062],{"class":662},[524,1746,1747],{"class":662},")),",[524,1749,1750],{"class":662}," nil\n",[524,1752,1754],{"class":526,"line":1753},18,[524,1755,748],{"class":662},[524,1757,1759],{"class":526,"line":1758},19,[524,1760,674],{"emptyLinePlaceholder":673},[524,1762,1764,1766,1768,1770,1772,1774,1777,1779,1781,1783,1785,1787,1789,1791,1793,1795,1797,1799,1801,1803,1805,1807,1809,1811,1813,1816],{"class":526,"line":1763},20,[524,1765,1492],{"class":662},[524,1767,918],{"class":662},[524,1769,1611],{"class":715},[524,1771,1497],{"class":530},[524,1773,605],{"class":662},[524,1775,1776],{"class":695}," ToDatabase",[524,1778,712],{"class":662},[524,1780,1545],{"class":530},[524,1782,722],{"class":662},[524,1784,725],{"class":530},[524,1786,728],{"class":662},[524,1788,971],{"class":530},[524,1790,722],{"class":662},[524,1792,592],{"class":530},[524,1794,605],{"class":662},[524,1796,918],{"class":662},[524,1798,921],{"class":530},[524,1800,728],{"class":662},[524,1802,874],{"class":702},[524,1804,605],{"class":662},[524,1806,1510],{"class":662},[524,1808,1513],{"class":658},[524,1810,1726],{"class":771},[524,1812,728],{"class":662},[524,1814,1815],{"class":662}," nil",[524,1817,1523],{"class":662},[515,1819,1822],{"className":650,"code":1820,"filename":1821,"language":531,"meta":520,"style":520},"func sendContactEmail(deps contact.Dependencies) func(context.Context, contactevents.ContactSubmitted) error {\n    requesterNotifier := contactmail.New(deps.Mailer)\n    return func(ctx context.Context, ev contactevents.ContactSubmitted) error {\n        payload := contactmail.ContactNotification{Name: ev.Name, Email: ev.Email \u002F* ... *\u002F}\n\n        adminErr := deps.Notifier.Send(ctx,\n            notify.Recipient{ID: \"admin\", Email: deps.Mail.AdminEmail},\n            contactnotifications.AdminNotification{ContactNotification: payload},\n        )\n        requesterErr := requesterNotifier.Notify(ctx, payload)\n        return errors.Join(adminErr, requesterErr)\n    }\n}\n","internal\u002Fmodules\u002Fcontact\u002Flisteners\u002Fsendcontactemail.go",[465,1823,1824,1871,1897,1928,1972,1976,2002,2045,2065,2070,2094,2119,2124],{"__ignoreMap":520},[524,1825,1826,1828,1831,1833,1836,1839,1841,1844,1846,1849,1851,1853,1855,1857,1860,1862,1865,1867,1869],{"class":526,"line":527},[524,1827,1492],{"class":662},[524,1829,1830],{"class":695}," sendContactEmail",[524,1832,712],{"class":662},[524,1834,1835],{"class":715},"deps",[524,1837,1838],{"class":530}," contact",[524,1840,722],{"class":662},[524,1842,1843],{"class":530},"Dependencies",[524,1845,605],{"class":662},[524,1847,1848],{"class":662}," func(",[524,1850,1545],{"class":530},[524,1852,722],{"class":662},[524,1854,725],{"class":530},[524,1856,728],{"class":662},[524,1858,1859],{"class":530}," contactevents",[524,1861,722],{"class":662},[524,1863,1864],{"class":530},"ContactSubmitted",[524,1866,605],{"class":662},[524,1868,874],{"class":702},[524,1870,689],{"class":662},[524,1872,1873,1876,1878,1881,1883,1886,1888,1890,1892,1895],{"class":526,"line":545},[524,1874,1875],{"class":771},"    requesterNotifier ",[524,1877,968],{"class":662},[524,1879,1880],{"class":771}," contactmail",[524,1882,722],{"class":662},[524,1884,1885],{"class":695},"New",[524,1887,712],{"class":662},[524,1889,1835],{"class":771},[524,1891,722],{"class":662},[524,1893,1894],{"class":771},"Mailer",[524,1896,877],{"class":662},[524,1898,1899,1901,1903,1905,1907,1909,1911,1913,1916,1918,1920,1922,1924,1926],{"class":526,"line":677},[524,1900,1570],{"class":658},[524,1902,1848],{"class":662},[524,1904,716],{"class":715},[524,1906,719],{"class":530},[524,1908,722],{"class":662},[524,1910,725],{"class":530},[524,1912,728],{"class":662},[524,1914,1915],{"class":715}," ev",[524,1917,1859],{"class":530},[524,1919,722],{"class":662},[524,1921,1864],{"class":530},[524,1923,605],{"class":662},[524,1925,874],{"class":702},[524,1927,689],{"class":662},[524,1929,1930,1933,1935,1937,1939,1941,1943,1946,1948,1950,1952,1954,1956,1958,1960,1962,1964,1967,1970],{"class":526,"line":692},[524,1931,1932],{"class":771},"        payload ",[524,1934,968],{"class":662},[524,1936,1880],{"class":530},[524,1938,722],{"class":662},[524,1940,1476],{"class":530},[524,1942,1048],{"class":662},[524,1944,1945],{"class":771},"Name",[524,1947,1054],{"class":662},[524,1949,1915],{"class":771},[524,1951,722],{"class":662},[524,1953,1945],{"class":771},[524,1955,728],{"class":662},[524,1957,1067],{"class":771},[524,1959,1054],{"class":662},[524,1961,1915],{"class":771},[524,1963,722],{"class":662},[524,1965,1966],{"class":771},"Email ",[524,1968,1969],{"class":541},"\u002F* ... *\u002F",[524,1971,748],{"class":662},[524,1973,1974],{"class":526,"line":706},[524,1975,674],{"emptyLinePlaceholder":673},[524,1977,1978,1981,1983,1986,1988,1991,1993,1995,1997,1999],{"class":526,"line":745},[524,1979,1980],{"class":771},"        adminErr ",[524,1982,968],{"class":662},[524,1984,1985],{"class":771}," deps",[524,1987,722],{"class":662},[524,1989,1990],{"class":771},"Notifier",[524,1992,722],{"class":662},[524,1994,1033],{"class":695},[524,1996,712],{"class":662},[524,1998,716],{"class":771},[524,2000,2001],{"class":662},",\n",[524,2003,2004,2007,2009,2011,2013,2015,2017,2019,2022,2024,2026,2028,2030,2032,2034,2037,2039,2042],{"class":526,"line":751},[524,2005,2006],{"class":530},"            notify",[524,2008,722],{"class":662},[524,2010,592],{"class":530},[524,2012,1048],{"class":662},[524,2014,1051],{"class":771},[524,2016,1054],{"class":662},[524,2018,663],{"class":662},[524,2020,2021],{"class":534},"admin",[524,2023,1062],{"class":662},[524,2025,728],{"class":662},[524,2027,1067],{"class":771},[524,2029,1054],{"class":662},[524,2031,1985],{"class":771},[524,2033,722],{"class":662},[524,2035,2036],{"class":771},"Mail",[524,2038,722],{"class":662},[524,2040,2041],{"class":771},"AdminEmail",[524,2043,2044],{"class":662},"},\n",[524,2046,2047,2050,2052,2054,2056,2058,2060,2063],{"class":526,"line":756},[524,2048,2049],{"class":530},"            contactnotifications",[524,2051,722],{"class":662},[524,2053,1497],{"class":530},[524,2055,1048],{"class":662},[524,2057,1476],{"class":771},[524,2059,1054],{"class":662},[524,2061,2062],{"class":771}," payload",[524,2064,2044],{"class":662},[524,2066,2067],{"class":526,"line":768},[524,2068,2069],{"class":662},"        )\n",[524,2071,2072,2075,2077,2080,2082,2084,2086,2088,2090,2092],{"class":526,"line":781},[524,2073,2074],{"class":771},"        requesterErr ",[524,2076,968],{"class":662},[524,2078,2079],{"class":771}," requesterNotifier",[524,2081,722],{"class":662},[524,2083,1230],{"class":695},[524,2085,712],{"class":662},[524,2087,716],{"class":771},[524,2089,728],{"class":662},[524,2091,2062],{"class":771},[524,2093,877],{"class":662},[524,2095,2096,2099,2102,2104,2107,2109,2112,2114,2117],{"class":526,"line":789},[524,2097,2098],{"class":658},"        return",[524,2100,2101],{"class":771}," errors",[524,2103,722],{"class":662},[524,2105,2106],{"class":695},"Join",[524,2108,712],{"class":662},[524,2110,2111],{"class":771},"adminErr",[524,2113,728],{"class":662},[524,2115,2116],{"class":771}," requesterErr",[524,2118,877],{"class":662},[524,2120,2121],{"class":526,"line":797},[524,2122,2123],{"class":662},"    }\n",[524,2125,2126],{"class":526,"line":1604},[524,2127,748],{"class":662},[448,2129,1205,2130,2132,2133,2135],{},[465,2131,1497],{}," ugyanazt a ",[465,2134,1476],{}," payloadot embeddeli, amit a beküldőmail renderel, így mindkét felület egy közös igazságforrásból szinkronban marad. Az admin pedig ingyen kap egy perzisztált, lekérdezhető notification-történetet, a beküldő-oldali rész változtatása nélkül.",[511,2137,2139],{"id":2138},"kapcsolódó-oldalak","Kapcsolódó oldalak",[2141,2142,2143,2148,2153,2158],"ul",{},[1097,2144,2145,2147],{},[457,2146,611],{"href":140},": a durable, lekérdezhető inbox-csatorna.",[1097,2149,2150,2152],{},[457,2151,624],{"href":144},": az élő push-csatorna és a Valkey-bekötése.",[1097,2154,2155,2157],{},[457,2156,268],{"href":269},": a gateway, ami a kliens-kapcsolatokat tartja a broadcast-csatornához.",[1097,2159,2160,1398,2162,2164],{},[457,2161,2036],{"href":119},[465,2163,1894],{},", amire ennek a modulnak a mail-csatornája delegál.",[2166,2167,2168],"style",{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}",{"title":520,"searchDepth":545,"depth":545,"links":2170},[2171,2172,2173,2174,2175,2176,2177,2178,2179],{"id":513,"depth":545,"text":25},{"id":627,"depth":545,"text":628},{"id":646,"depth":545,"text":647},{"id":954,"depth":545,"text":955},{"id":1145,"depth":545,"text":1146},{"id":1248,"depth":545,"text":305},{"id":1335,"depth":545,"text":169},{"id":1418,"depth":545,"text":1419},{"id":2138,"depth":545,"text":2139},"Többcsatornás notificationök: egy payload, több csatorna (database, mail, broadcast), egy közös Hub vezérli.","md",null,{},{"icon":131},{"title":52,"description":2180},"1Y8_BLNNK_dFBBO_OmlI2TG2BUIUrqge2WMApd0OvQY",[2188,2190],{"title":126,"path":127,"stem":128,"description":2189,"icon":114,"children":-1},"MJML sablonozás mailhez.",{"title":139,"path":140,"stem":141,"description":2191,"icon":131,"children":-1},"A tartós database notification csatorna.",1785445882076]