[{"data":1,"prerenderedAt":915},["ShallowReactive",2],{"navigation_docs_hu":3,"-hu-getting-started-project-structure":442,"-hu-getting-started-project-structure-surround":910},[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":35,"body":444,"description":903,"extension":904,"links":905,"meta":906,"navigation":907,"path":36,"seo":908,"stem":37,"__hash__":909},"docs_hu\u002Fhu\u002F1.getting-started\u002F6.project-structure.md",{"type":445,"value":446,"toc":895},"minimark",[447,456,467,493,498,501,613,649,680,707,711,714,720,802,806,830,834,853,864,868],[448,449,450,451,455],"p",{},"Így néz ki a ",[452,453,454],"a",{"href":41},"shop mintaalkalmazás"," a teljes kiépítés után: két surface-szel, workerrel, eventekkel és migrációkkal:",[457,458,463],"pre",{"className":459,"code":461,"language":462},[460],"language-text","shop\u002F\n├── gpsystem.yaml                 # generátor-manifest: projektnév, module path, kit verzió,\n│                                 # db (pgx|bun), template checksum, modulok+surface-ök\n├── go.mod                        # require gpsystem + tool directive-ek (gpsystem, oapi-codegen)\n├── mise.toml                     # taskok: setup \u002F spec \u002F generate \u002F dev \u002F restart \u002F build \u002F test\n├── Dockerfile                    # 4 stage: base \u002F development (bind-mount, go run) \u002F build \u002F production\n├── .dockerignore\n├── compose.yml                   # teljes dev-stack: postgres, valkey, mailpit, rustfs, migrate,\n│                                 # worker, modul-service-ek, nulla publikált port, Traefik\u002Fproxynet\n├── .env.example\n├── spec\u002Ftypespec\u002F                # ★ az API kontraktus (source of truth)\n│   ├── main.tsp                  # minden modult importál (anchorral kezelve)\n│   ├── lib\u002F                      # @permission \u002F @policy dekorátorok\n│   ├── shared\u002Ferrors.tsp         # ProblemDetail + FieldError (a httperr tükre)\n│   ├── shared\u002Fpaginator.tsp\n│   └── modules\u002F\u003Cmodul>\u002F          # modulonként: \u003Csurface>.tsp + models\u002F\n├── api\u002F\n│   ├── openapi\u002F                  # emittált OpenAPI 3.0 (commitolva, review-olható diffekért)\n│   └── oapi-codegen\u002F\n│       ├── templates\u002F            # a projekt codegen template-jei (upstream chi-server\n│       │                         # + a kit minimális strict-felülírásai)\n│       └── \u003Cmodul>-\u003Csurface>.yaml\n├── cmd\u002F\n│   ├── \u003Cmodul>\u002Fmain.go           # modulonként egy HTTP belépési pont (~20 sor)\n│   ├── worker\u002Fmain.go            # háttérfeldolgozó: asynq szerver + outbox relay + scheduler\n│   └── migrate\u002Fmain.go           # migrációfuttató\n├── internal\u002F\n│   ├── platform\u002Fconfig\u002Fconfig.go # összerakott env konfig (Server + DB + Worker + Outbox [+ JWT])\n│   └── modules\u002F\u003Cmodul>\u002F\n│       ├── register.go           # Dependencies struct + surface-enként egy Register\u003CSurface>(router, deps)\n│       ├── core\u002F                 # a modul KÖZÖS üzleti logikája: entitások\u002Fnézetek, szabályok,\n│       │                         # sentinel-hibák (pl. ErrNotFound); minden surface ezt használja\n│       ├── repository\u002F           # a modul EGYETLEN perzisztencia-rétege (sor-structok +\n│       │                         # interfész + implementáció); nevesített kapcsolatnál repository\u002F\u003Ckapcsolat>\u002F\n│       ├── events\u002F               # a modul eventjei (struct + EventName)\n│       ├── listeners\u002F            # a modul worker-listenerei\n│       │   ├── register.go       # events.Listen(...) regisztrációk a workerhez\n│       │   └── \u003Cnév>.go          # listener-törzsek\n│       ├── jobs\u002F                 # a modul worker-jobjai\n│       │   ├── register.go       # sched.Job(...) regisztrációk a workerhez\n│       │   └── \u003Cnév>.go          # job-törzsek\n│       ├── mail\u002F                 # a modul mail-notifierjei (payload + sablonok)\n│       │   └── \u003Cnév>.go          # notifier-törzs + templates\u002F\u003Cnév>.{html,txt}.tmpl\n│       ├── notifications\u002F        # a modul többcsatornás notificationjei (payload + Via)\n│       │   └── \u003Cnév>.go          # notification-törzs + templates\u002F\u003Cnév>.{html,txt}.tmpl\n│       └── surfaces\u002F\n│           └── \u003Csurface>\u002F        # bármely név (api | web | admin | ...); az \"api\" a modul gyökerére mountol\n│               ├── http\u002Fhandler.go   # a generált szigorú interfészt implementálja\n│               ├── http\u002Fmapper\u002F      # DTO ↔ service típus mappelés (üresen tartva)\n│               ├── http\u002Fgen\u002F         # oapi-codegen kimenet, soha ne szerkeszd\n│               ├── policy\u002F           # policy registry (@permission\u002F@policy érvényesítéshez)\n│               └── service\u002F          # vékony, célközönség-specifikus varrat: a core-ba delegál\n└── migrations\u002F                   # időbélyeg-prefixes SQL migrációk (20200101000000_init.sql, 20200101000100_outbox.sql, ...)\n","text",[464,465,461],"code",{"__ignoreMap":466},"",[448,468,469,470,473,474,473,477,473,480,483,484,487,488,492],{},"A worker-réteg (",[464,471,472],{},"cmd\u002Fworker",", ",[464,475,476],{},"listeners\u002F",[464,478,479],{},"jobs\u002F",[464,481,482],{},"events\u002F",") az új projektekben alapból ott van; ha egy projekt ",[464,485,486],{},"new project --no-worker","-rel készült, az ",[452,489,491],{"href":490},"\u002Fhu\u002Fcli\u002Fworker-generators#add-worker","add worker"," adja hozzá.",[494,495,497],"h2",{"id":496},"mi-élhet-egy-modulon-belül","Mi élhet egy modulon belül",[448,499,500],{},"Egy modul mappájában négyféle, egymástól jól elkülönítendő dolog lehet:",[502,503,504,520],"table",{},[505,506,507],"thead",{},[508,509,510,514,517],"tr",{},[511,512,513],"th",{},"Fajta",[511,515,516],{},"Mappák",[511,518,519],{},"Mi ez",[521,522,523,551,573,590],"tbody",{},[508,524,525,529,538],{},[526,527,528],"td",{},"Surface-ök",[526,530,531,473,534,537],{},[464,532,533],{},"surfaces\u002Fapi\u002F",[464,535,536],{},"surfaces\u002Fadmin\u002F",", ...",[526,539,540,541,544,545,544,548],{},"Párhuzamos, célközönségenkénti HTTP felületkötegek: ",[464,542,543],{},"http"," + ",[464,546,547],{},"service",[464,549,550],{},"policy",[508,552,553,556,564],{},[526,554,555],{},"Közös mag",[526,557,558,473,561],{},[464,559,560],{},"core\u002F",[464,562,563],{},"repository\u002F",[526,565,566,567,569,570,572],{},"Amit minden surface megoszt: az üzleti szabályok és entitások (",[464,568,560],{},"), plusz a modul egyetlen perzisztencia-rétege (",[464,571,563],{},")",[508,574,575,578,584],{},[526,576,577],{},"Trigger-egységek",[526,579,580,473,582],{},[464,581,479],{},[464,583,476],{},[526,585,586,587,589],{},"Alternatív belépési pontok: idő vagy esemény hívja, HTTP helyett; a ",[464,588,472],{},"-be vannak bekötve",[508,591,592,595,605],{},[526,593,594],{},"Kontraktok és tartalom",[526,596,597,473,599,473,602],{},[464,598,482],{},[464,600,601],{},"mail\u002F",[464,603,604],{},"notifications\u002F",[526,606,607,608,612],{},"Amit a modul ",[609,610,611],"em",{},"termel",": event-payloadok, üzenettartalom és sablonok",[614,615,616,617,621,622,625,626,625,629,632,633,636,637,639,640,643,644,648],"note",{},"Egy ",[618,619,620],"strong",{},"surface"," egy célközönségenkénti felületköteg: egy publikus ",[464,623,624],{},"api",", egy ",[464,627,628],{},"admin",[464,630,631],{},"web",", mind ugyanannak a modulnak egy-egy párhuzamos HTTP-felülete. A ",[618,634,635],{},"core"," a modul közös üzleti logikája (sima structok metódusokkal, egyszer leírt szabályok), nem DDD-féle \"domain layer\". A surface-enkénti ",[618,638,547],{}," a célközönség-specifikus varrat: DDD-fogalmakkal az ",[609,641,642],{},"application service"," szerepét tölti be, és a közös szabályokhoz a core-ba delegál. Lásd a ",[452,645,647],{"href":646},"\u002Fhu\u002Fconcepts\u002Fdesign-patterns#service-layer","design pattern-eket"," az indoklásért.",[448,650,651,652,665,666,473,669,672,673,676,677,679],{},"Az ökölszabály: ",[618,653,654,655,658,659,661,662,664],{},"a csatorna\u002Fdriver-kód a kitben vagy az ",[464,656,657],{},"internal\u002Fplatform","-ban él, a tartalom a modulban, a trigger a ",[464,660,479],{},"\u002F",[464,663,476],{},"-ben."," A mail a legtisztább példa: az SMTP-transzport (",[464,667,668],{},"gpsystem\u002Fmail",[464,670,671],{},"gpsystem\u002Fmail\u002Fsmtp",") infrastruktúra, pont úgy mint az adatbázis-driver, a kitben él. Hogy milyen e-mailt küldünk, milyen subjecttel és sablonnal, az a contact modul üzleti tartalma, az ",[464,674,675],{},"internal\u002Fmodules\u002Fcontact\u002Fmail\u002F","-ban él. Lásd a ",[452,678,113],{"href":119}," oldal kidolgozott példáját.",[448,681,682,683,686,687,690,691,694,695,698,699,702,703,706],{},"Ugyanez a szétválasztás egy szinttel feljebb is érvényes a ",[452,684,685],{"href":136},"notificationökre",": egy notification ",[609,688,689],{},"csatornáit"," (mail, database, broadcast) a kit adja (",[464,692,693],{},"gpsystem\u002Fnotify",", plusz a driver-specifikus ",[464,696,697],{},"gpsystem\u002Fnotify\u002Fdatabase"," és ",[464,700,701],{},"gpsystem\u002Fnotify\u002Fbroadcast","), míg hogy egy notification mit mond (payload, subject, sablonok), az modultartalom az ",[464,704,705],{},"internal\u002Fmodules\u002F\u003Cmodul>\u002Fnotifications\u002F","-ban.",[494,708,710],{"id":709},"rétegszabályok","Rétegszabályok",[448,712,713],{},"A függőségi irány egyirányú:",[457,715,718],{"className":716,"code":717,"language":462},[460],"http (handler) → service → core → repository\n",[464,719,717],{"__ignoreMap":466},[721,722,723,735,748,765,792],"ul",{},[724,725,726,727,730,731,734],"li",{},"A handler soha nem nyúl adatbázishoz; inputot köt\u002Fvalidál, a saját surface-e service-ét hívja és eredményt mappel. ",[618,728,729],{},"A handler soha nem importálja a repository csomagot",": a sentinel-hibákat (pl. \"nincs ilyen rekord\") a repository vagy a core definiálja, és a core\u002Fservice exportálja tovább, így a handler mindig csak a saját surface-e service csomagját ellenőrzi (",[464,732,733],{},"errors.Is(err, service.ErrNotFound)",").",[724,736,737,738,740,741,743,744,747],{},"A surface-enkénti ",[464,739,547],{}," vékony, célközönség-specifikus varrat: a közös szabályokhoz a ",[464,742,635],{},"-ba delegál, és csak a saját felületének folyamatait tartja. Repository-",[618,745,746],{},"interfészektől"," függ, így sima fake-ekkel tesztelhető.",[724,749,750,751,753,754,757,758,761,762],{},"A ",[464,752,635],{}," a modul közös üzleti logikája: az entitások\u002Fnézetek, az egyszer leírt szabályok és a sentinel-hibák. Eseményt a szabály helyén dobunk, a ",[452,755,756],{"href":423},"tranzakción belül",", a ",[464,759,760],{},"Dependencies","-ben kapott dispatcheren át. ",[618,763,764],{},"A core soha nem importál surface-csomagot.",[724,766,767,768,770,771,776,777,780,781,783,784,787,788,734],{},"A modulszintű ",[464,769,563],{}," tartalmazza az SQL-t, a sor-structokat és az interfészt+implementációt, modulonként egyszer, minden surface számára közösen. ",[452,772,773],{"href":415},[464,774,775],{},"pg.DBTX","-et kap, így ugyanaz a kód fut poolon vagy tranzakcióban, anélkül hogy tudna róla, vagy ",[464,778,779],{},"--db bun"," projektben a ",[452,782,418],{"href":419}," megfelelője. Egy modul repositoryja egy DB engine-t használ; nevesített kapcsolatnál ",[464,785,786],{},"repository\u002F\u003Ckapcsolat>\u002F"," almappára bomlik (",[452,789,790],{"href":291},[464,791,290],{},[724,793,750,794,797,798,801],{},[464,795,796],{},"policy\u002F"," a surface kérés-szintű jogosultsági szabályait tartja: a ",[452,799,800],{"href":99},"policy réteg"," a generált enforcer middleware-en át hívja.",[494,803,805],{"id":804},"két-bináris-egy-életciklus","Két bináris, egy életciklus",[448,807,750,808,811,812,814,815,821,822,825,826,829],{},[464,809,810],{},"cmd\u002F\u003Cmodul>"," a HTTP-oldalt futtatja, a ",[464,813,472],{}," a háttérfeldolgozást, mindkettő ugyanarra az ",[452,816,817,820],{"href":254},[464,818,819],{},"app"," életciklusra"," épül: azonos graceful shutdown, azonos telemetria-bekötés. Külön skálázod őket: több HTTP-replika, több worker-replika. Az ",[452,823,824],{"href":73},"outbox"," és a ",[452,827,828],{"href":78},"scheduler"," replikabiztos.",[494,831,833],{"id":832},"generált-vs-saját","Generált vs. saját",[448,835,836,837,840,841,844,845,848,849,852],{},"Csak a ",[464,838,839],{},"http\u002Fgen\u002F"," újragenerált kimenet (és jelölve is van). Minden más (handlerek, service-ek, repositoryk, a ",[464,842,843],{},".tsp"," fájlok, a listener\u002Fjob törzsek) normál kód, amit szerkesztesz. A generátorok kizárólag ",[464,846,847],{},"\u002F\u002F gpsystem:*"," anchor-kommenteknél bővítenek meglévő fájlt; lásd a ",[452,850,851],{"href":287},"CLI áttekintést",".",[614,854,855,856,859,860,863],{},"Az ",[464,857,858],{},"api\u002Fopenapi\u002F*.yaml"," szándékosan commitolva van: az API-változások review-olható diffként jelennek meg a pull requestekben, és a ",[464,861,862],{},"go build"," soha nem függ a Node toolchaintől.",[494,865,867],{"id":866},"hova-kerüljön-a-közös-kód","Hova kerüljön a közös kód?",[448,869,870,871,874,875,878,879,882,883,886,887,889,890,894],{},"Egy generált projektben nincs ",[464,872,873],{},"pkg\u002F"," és nincs ",[464,876,877],{},"internal\u002Fpkg\u002F",": az ",[464,880,881],{},"internal\u002F"," már önmagában privátat jelent, egy második réteg alatta csak egy szemetesfiókot hívna életre. Az ",[464,884,885],{},"internal\u002Fplatform\u002Fconfig\u002F"," az egyetlen app-szintű közös mappa, amivel egy friss projekt indul. Modulon belül a több surface által megosztott szabályok helye a generált ",[464,888,560],{},"; lásd a ",[452,891,893],{"href":892},"\u002Fhu\u002Fconcepts\u002Farchitecture#k%C3%B6z%C3%B6s-k%C3%B3d-egy-d%C3%B6nt%C3%A9si-l%C3%A9tra","Közös kód: egy döntési létra"," szekciót arról, hova kerüljön a több surface vagy modul által használt kód.",{"title":466,"searchDepth":896,"depth":896,"links":897},2,[898,899,900,901,902],{"id":496,"depth":896,"text":497},{"id":709,"depth":896,"text":710},{"id":804,"depth":896,"text":805},{"id":832,"depth":896,"text":833},{"id":866,"depth":896,"text":867},"Egy generált fogyasztó projekt felépítése és a mögötte lévő szabályok.","md",null,{},{"icon":38},{"title":35,"description":903},"la4wQeMDuA7vGikDp46xtveyxFey0Te1c_8i8EqMbE8",[911,913],{"title":30,"path":31,"stem":32,"description":912,"icon":33,"children":-1},"Modul generálása, a codegen lánc futtatása és a service bootolása.",{"title":40,"path":41,"stem":42,"description":914,"icon":43,"children":-1},"Egy végigvitt példaprojekt, a dokumentáció minden kódpéldája erre épül.",1785445881258]