{"navigation":[{"section":"api","documents":[{"slug":"rest-api","title":"REST API","summary":"Classic Semitexa REST endpoints with typed payloads, versioning, and consumer-friendly response shaping.","href":"/docs/api/rest-api"},{"slug":"structured-errors","title":"Structured Errors","summary":"Throw domain exceptions and let semitexa-api map them into stable machine-readable error envelopes.","href":"/docs/api/structured-errors"},{"slug":"active-version","title":"Active Version","summary":"The current collection endpoint with a clean X-Api-Version header and no deprecation noise.","href":"/docs/api/active-version"},{"slug":"sunset-version","title":"Sunset Version","summary":"A deprecated product endpoint that emits both Deprecation and Sunset headers.","href":"/docs/api/sunset-version"},{"slug":"schema-discovery","title":"Schema Discovery","summary":"A mini Swagger-style explorer for the live product API contract, schema endpoint, and response shapes.","href":"/docs/api/schema-discovery"},{"slug":"graphql","title":"GraphQL API","summary":"GraphQL-first Semitexa contracts built with typed payloads and typed output DTOs instead of resolver sprawl.","href":"/docs/api/graphql"},{"slug":"rest-graphql","title":"REST + GraphQL","summary":"One Semitexa use case can serve both REST and GraphQL without duplicating handler logic into separate resolver classes.","href":"/docs/api/rest-graphql"}]},{"section":"auth","documents":[{"slug":"session","title":"Session Auth","summary":"Google signs the user in, then the session stores the selected demo role and re-hydrates it on every request.","href":"/docs/auth/session"},{"slug":"session-payloads","title":"Session Payloads","summary":"Semitexa forbids string-key session chaos: session state lives in typed Session Payloads or it does not exist.","href":"/docs/auth/session-payloads"},{"slug":"google","title":"Google Authorization","summary":"Authorization is required for demo SSE blocks that keep a long-lived backend connection open.","href":"/docs/auth/google"},{"slug":"machine","title":"Machine Auth","summary":"Service-to-service authentication via Bearer tokens — scoped, revocable, and audited.","href":"/docs/auth/machine"},{"slug":"protected","title":"Protected Route","summary":"Add one access attribute and one optional permission attribute and the framework enforces access — 401 for unauthenticated requests, 403 for unauthorized ones.","href":"/docs/auth/protected"},{"slug":"requires-permission","title":"Requires Permission","summary":"Declare one permission slug on the payload and let the framework enforce it before your handler runs.","href":"/docs/auth/requires-permission"},{"slug":"rbac","title":"RBAC","summary":"Hybrid RBAC with coarse-grained capabilities, exact permission slugs, and module-owned permission catalogs.","href":"/docs/auth/rbac"}]},{"section":"cli","documents":[{"slug":"describe-commands","title":"Project Graph Introspection","summary":"Routes, modules, contracts, and handlers can be introspected directly from the CLI instead of reverse-engineering the framework graph by hand.","href":"/docs/cli/describe-commands"},{"slug":"runtime-maintenance","title":"Runtime Maintenance","summary":"Reload workers, clear stale cache, sync registries, lint architecture rules, and probe handler wiring without reaching for ad-hoc shell scripts.","href":"/docs/cli/runtime-maintenance"},{"slug":"scaffolding-generators","title":"Scaffolding Generators","summary":"Scaffold modules, pages, payloads, services, and contracts through commands that already understand Semitexa structure and AI-friendly output modes.","href":"/docs/cli/scaffolding-generators"},{"slug":"workers-scheduling","title":"Workers & Scheduling","summary":"Run queues, scheduler pools, mail delivery, webhooks, and tenant-scoped commands from a coherent operator surface instead of bespoke daemons.","href":"/docs/cli/workers-scheduling"},{"slug":"ai-tooling","title":"AI Tooling Surface","summary":"Semitexa exposes AI-facing commands as explicit CLI contracts: capabilities, skills, log access, and a local assistant entrypoint.","href":"/docs/cli/ai-tooling"},{"slug":"orm-console","title":"ORM Console Toolkit","summary":"The ORM ships with a practical CLI surface: status, diff, sync, and seed commands with dry-run safety and SQL plan export.","href":"/docs/cli/orm-console"}]},{"section":"data","documents":[{"slug":"domain-models","title":"Domain-Level Models","summary":"Semitexa separates persistence resources from business models. Resources map tables; domain models carry behavior and invariants.","href":"/docs/data/domain-models"},{"slug":"repository-workflow","title":"Repository Workflow","summary":"The canonical Semitexa path: handlers depend on repository contracts, repositories return domain models, and persistence resources stay behind the boundary.","href":"/docs/data/repository-workflow"},{"slug":"schema-sync","title":"Schema Sync, Not Migration Churn","summary":"Semitexa creates SQL only when the real schema changed, blocks destructive drops by default, and logs the exact DDL plan as SQL and JSON.","href":"/docs/data/schema-sync"},{"slug":"query","title":"Query Builder","summary":"Compose type-safe queries with a fluent API — no raw SQL, no magic strings.","href":"/docs/data/query"},{"slug":"filtering","title":"Filtering","summary":"Mark a property #[Filterable] and the ORM handles the rest — no manual WHERE clauses.","href":"/docs/data/filtering"},{"slug":"pagination","title":"Pagination","summary":"Offset and cursor pagination out of the box — switch modes with a single query parameter.","href":"/docs/data/pagination"},{"slug":"relations","title":"Relations","summary":"Declare parent and child links on the resource itself, then read typed relations from the handler.","href":"/docs/data/relations"},{"slug":"table-extension","title":"Shared Table Extension","summary":"Two modules can extend one table independently, and the ORM merges the schema without forcing either side to edit the other.","href":"/docs/data/table-extension"},{"slug":"n-plus-one","title":"N+1 Without Magic","summary":"Semitexa avoids N+1 by using resource slices for the exact columns and relations each screen needs, instead of hiding database traffic behind implicit relation loading.","href":"/docs/data/n-plus-one"},{"slug":"orm-guide","title":"ORM Working Guide","summary":"Declaring a resource, querying it, relations and write policies, optimistic locking, transactions, wiring a store, and the gotchas.","href":"/docs/data/orm-guide"}]},{"section":"di","documents":[{"slug":"overview","title":"DI Canon","summary":"One canonical DI path for container-managed classes — protected property attributes, no constructor arguments, validated at boot and enforced by lint:di.","href":"/docs/di/overview"},{"slug":"services","title":"Declaring a Service","summary":"#[AsService] makes a plain class a worker-scoped singleton the container will build and inject — and when you do not need it.","href":"/docs/di/services"},{"slug":"readonly","title":"Readonly Injection","summary":"The default tier — one instance per worker, injected into a protected property, with optional injection for dependencies that may not be installed.","href":"/docs/di/readonly"},{"slug":"mutable","title":"Mutable Injection","summary":"#[ExecutionScoped] opts a class into a per-execution clone; #[InjectAsMutable] marks the properties re-injected on that clone.","href":"/docs/di/mutable"},{"slug":"factory","title":"Factory Injection","summary":"#[InjectAsFactory] injects a ContractFactory that selects among a contract's implementations by backed-enum key — not a closure, and not a new instance per call.","href":"/docs/di/factory"},{"slug":"configuration","title":"Configuration Injection","summary":"#[Config] reads a scalar from the environment into a typed property, with a default in code — the only supported way a container-managed class reads env.","href":"/docs/di/configuration"},{"slug":"contracts","title":"Service Contracts","summary":"One module declares an interface, implementations advertise themselves with SatisfiesServiceContract, and the active one is visible in contracts:list.","href":"/docs/di/contracts"},{"slug":"contract-resolution","title":"Resolving Service Contracts","summary":"Seeing which implementation is bound to a contract, using a resolver as a factory, and the Factory* naming convention for choosing by key.","href":"/docs/di/contract-resolution"},{"slug":"discovery-contributors","title":"Discovery Contributors","summary":"How a package teaches boot-time discovery to recognise its own attribute, with priority ordering and per-class error isolation.","href":"/docs/di/discovery-contributors"}]},{"section":"events","documents":[{"slug":"arena","title":"Execution Arena","summary":"Launch the same backend intent in sync, Swoole async, and queued modes, then watch the proof arrive over SSE.","href":"/docs/events/arena"},{"slug":"sync","title":"Sync Events","summary":"Dispatch an event and all sync listeners run before the response is sent.","href":"/docs/events/sync"},{"slug":"deferred","title":"Deferred Handler","summary":"Heavy work runs after the response is sent — the user gets instant feedback.","href":"/docs/events/deferred"},{"slug":"queued","title":"Queued Handler","summary":"Events survive restarts and scale across workers — backed by a durable message queue.","href":"/docs/events/queued"},{"slug":"sse","title":"SSE Stream","summary":"Real-time server push without WebSockets — connect once and receive real backend events over plain HTTP.","href":"/docs/events/sse"},{"slug":"ledger","title":"Ledger Demo","summary":"Dispatch a protected demo event and inspect only the persisted demo ledger rows through a safe read-only view.","href":"/docs/events/ledger"},{"slug":"pipeline","title":"Request Pipeline Events","summary":"The events every request passes through -- AuthCheck, AccessCheck, HandleRequest -- and the Swoole server lifecycle hooks around them.","href":"/docs/events/pipeline"},{"slug":"dispatch-configuration","title":"Domain Event Dispatch and Configuration","summary":"Choosing sync or async per handler, the HandlerCompleted event, running the async worker, and how the three event kinds compare.","href":"/docs/events/dispatch-configuration"}]},{"section":"get-started","documents":[{"slug":"installation","title":"Installation","summary":"Create the project, review the baseline env contract, and bring up the Semitexa runtime the supported way.","href":"/docs/get-started/installation"},{"slug":"local-domain","title":"Local Domain","summary":"Register .test domains through the built-in local-domain helper instead of relying on ad hoc host setup.","href":"/docs/get-started/local-domain"},{"slug":"module-structure","title":"Module Structure","summary":"The minimal Semitexa module is a typed HTTP spine of payload, handler, resource, and template.","href":"/docs/get-started/module-structure"},{"slug":"base-tenant","title":"Base Tenant","summary":"Establish one default tenant context early so tenant-aware behavior is visible before the rest of the application grows.","href":"/docs/get-started/base-tenant"},{"slug":"locale-setup","title":"Locale Setup","summary":"Configure the minimal Locale contract so translations and locale-aware rendering become explicit early.","href":"/docs/get-started/locale-setup"},{"slug":"ai-console","title":"AI Console","summary":"Use the Semitexa AI console as a command translation surface over real operator commands.","href":"/docs/get-started/ai-console"},{"slug":"beyond-controllers","title":"Beyond Controllers","summary":"Understand why Semitexa keeps transport, use case, and rendering as separate explicit responsibilities.","href":"/docs/get-started/beyond-controllers"}]},{"section":"llm","documents":[{"slug":"overview","title":"LLM Module Overview","summary":"What `semitexa/llm` adds to the framework and how your project can expose its own CLI skills to the assistant.","href":"/docs/llm/overview"},{"slug":"providers","title":"Providers & Backends","summary":"Provider contracts, backend resolution, local vs remote Ollama, and the environment knobs that shape LLM runtime behavior.","href":"/docs/llm/providers"},{"slug":"skills","title":"Adding Skills","summary":"How a console command becomes AI-executable through `#[AsAiSkill]`, metadata policy, and registry discovery.","href":"/docs/llm/skills"},{"slug":"execution-flow","title":"Execution Flow","summary":"How a user request becomes a planner decision, a reviewed skill proposal, and finally a real console execution.","href":"/docs/llm/execution-flow"},{"slug":"skill-contract","title":"AsAiSkill Contract","summary":"What a class must satisfy to be discovered and invoked as an AI skill.","href":"/docs/llm/skill-contract"},{"slug":"prompt-reference","title":"LLM Prompt Reference","summary":"The prompt surface the platform exposes to language models.","href":"/docs/llm/prompt-reference"}]},{"section":"migration","documents":[{"slug":"post-hardening","title":"Post-Hardening Migration Guide","summary":"Migrate from the legacy access model and webhook flow to Semitexa's current architecture — explicit access attributes, tenant-aware webhooks, atomic replay protection, and the unified quality gate.","href":"/docs/migration/post-hardening"}]},{"section":"platform","documents":[{"slug":"tenancy-resolution","title":"Tenant Context Resolution","summary":"See how Semitexa resolves the active tenant from subdomain, header, path, or query input before the rest of the platform runs.","href":"/docs/platform/tenancy-resolution"},{"slug":"tenancy-config","title":"Per-Tenant Configuration","summary":"Three demo tenants with distinct branding -- switch tenant, everything changes without if/else.","href":"/docs/platform/tenancy-config"},{"slug":"tenancy-layers","title":"Multi-Layer Tenancy","summary":"Organization, Locale, Theme, Environment -- four independent layers compose into one TenantContext.","href":"/docs/platform/tenancy-layers"},{"slug":"tenancy-isolation","title":"Data Isolation","summary":"Product listing scoped by tenant -- switch tenant, list changes. Zero manual WHERE clauses.","href":"/docs/platform/tenancy-isolation"},{"slug":"tenancy-queue","title":"Queue Tenant Propagation","summary":"Tenant context travels with queued jobs -- _tenant key injected automatically, restored by worker.","href":"/docs/platform/tenancy-queue"},{"slug":"skin-generation","title":"Skin Generation","summary":"Generating a skin: inputs, the generation pipeline and what lands on disk.","href":"/docs/platform/skin-generation"},{"slug":"skin-algorithms","title":"Skin Algorithms and Knobs","summary":"The algorithms behind skin generation and every knob you can turn.","href":"/docs/platform/skin-algorithms"},{"slug":"skin-refinement","title":"Skin Refinement","summary":"Refining an existing skin with skin:refine instead of regenerating it.","href":"/docs/platform/skin-refinement"}]},{"section":"project-graph","documents":[{"slug":"overview","title":"Project Graph Overview","summary":"Understand what `semitexa-project-graph` adds: a stored structural map, an intelligence layer, and task-scoped context for large-codebase work.","href":"/docs/project-graph/overview"},{"slug":"inspection","title":"Inspecting the Graph","summary":"Use Project Graph queries and intelligence views to inspect modules, dependencies, flows, events, and hotspots without reconstructing the repository manually.","href":"/docs/project-graph/inspection"},{"slug":"impact","title":"Impact, Context, and Watch Mode","summary":"Use impact analysis, context packing, and watch mode to scope risky changes and keep graph-backed answers current during long work sessions.","href":"/docs/project-graph/impact"},{"slug":"architecture","title":"Project Graph Architecture","summary":"How the graph is built: parsers, the extractor pipeline, node and edge types, and which attribute produces which node.","href":"/docs/project-graph/architecture"},{"slug":"commands","title":"Project Graph Command Reference","summary":"Every ai:review-graph command with its options, output shape and a worked example.","href":"/docs/project-graph/commands"},{"slug":"intelligence","title":"Graph Intelligence","summary":"How the graph scores relevance, traces flows and infers intent, and what the intelligence commands return.","href":"/docs/project-graph/intelligence"},{"slug":"ai-integration","title":"Using the Graph as AI Context","summary":"Feeding graph slices to an assistant: what to ask for, what comes back, and how it beats grep.","href":"/docs/project-graph/ai-integration"}]},{"section":"prompt","documents":[{"slug":"overview","title":"Prompt Catalog Overview","summary":"What `semitexa/prompt` adds to the framework — an ORM-style catalog that turns inline prompt strings into addressable, versionable, override-aware records.","href":"/docs/prompt/overview"},{"slug":"catalog","title":"Defining Prompts","summary":"Declare a prompt with `#[AsPrompt]` and a standalone Twig body; the catalog discovers it like any other framework attribute.","href":"/docs/prompt/catalog"},{"slug":"rendering","title":"Rendering & Self-Binding","summary":"How PromptRenderer compiles a prompt with Twig, and how a self-binding prompt exposes its typed data to the template through getter dot-access.","href":"/docs/prompt/rendering"},{"slug":"overrides","title":"Per-Tenant Overrides","summary":"A DB-backed override layer lets each tenant edit a prompt on top of the code catalog, with version history and restore.","href":"/docs/prompt/overrides"},{"slug":"cli","title":"Prompt CLI","summary":"Inspect, render, override, and evaluate catalog prompts from the console.","href":"/docs/prompt/cli"}]},{"section":"reference","documents":[{"slug":"README","title":"Reference","summary":"What each part of the public surface is, generated from the code itself.","href":"/docs/reference/README"},{"slug":"attributes-api","title":"Api attributes","summary":"Every attribute declared by `Api`, with the signature the code has and a usage quoted from the codebase.","href":"/docs/reference/attributes-api"},{"slug":"attributes-auth","title":"Auth attributes","summary":"Every attribute declared by `Auth`, with the signature the code has and a usage quoted from the codebase.","href":"/docs/reference/attributes-auth"},{"slug":"attributes-authorization","title":"Authorization attributes","summary":"Every attribute declared by `Authorization`, with the signature the code has and a usage quoted from the codebase.","href":"/docs/reference/attributes-authorization"},{"slug":"attributes-core","title":"Core attributes","summary":"Every attribute declared by `Core`, with the signature the code has and a usage quoted from the codebase.","href":"/docs/reference/attributes-core"},{"slug":"attributes-graphql","title":"Graphql attributes","summary":"Every attribute declared by `Graphql`, with the signature the code has and a usage quoted from the codebase.","href":"/docs/reference/attributes-graphql"},{"slug":"attributes-ledger","title":"Ledger attributes","summary":"Every attribute declared by `Ledger`, with the signature the code has and a usage quoted from the codebase.","href":"/docs/reference/attributes-ledger"},{"slug":"attributes-llm","title":"Llm attributes","summary":"Every attribute declared by `Llm`, with the signature the code has and a usage quoted from the codebase.","href":"/docs/reference/attributes-llm"},{"slug":"attributes-media","title":"Media attributes","summary":"Every attribute declared by `Media`, with the signature the code has and a usage quoted from the codebase.","href":"/docs/reference/attributes-media"},{"slug":"attributes-orm","title":"Orm attributes","summary":"Every attribute declared by `Orm`, with the signature the code has and a usage quoted from the codebase.","href":"/docs/reference/attributes-orm"},{"slug":"attributes-platformui","title":"PlatformUi attributes","summary":"Every attribute declared by `PlatformUi`, with the signature the code has and a usage quoted from the codebase.","href":"/docs/reference/attributes-platformui"},{"slug":"attributes-projectgraph","title":"ProjectGraph attributes","summary":"Every attribute declared by `ProjectGraph`, with the signature the code has and a usage quoted from the codebase.","href":"/docs/reference/attributes-projectgraph"},{"slug":"attributes-prompt","title":"Prompt attributes","summary":"Every attribute declared by `Prompt`, with the signature the code has and a usage quoted from the codebase.","href":"/docs/reference/attributes-prompt"},{"slug":"attributes-scheduler","title":"Scheduler attributes","summary":"Every attribute declared by `Scheduler`, with the signature the code has and a usage quoted from the codebase.","href":"/docs/reference/attributes-scheduler"},{"slug":"attributes-ssr","title":"Ssr attributes","summary":"Every attribute declared by `Ssr`, with the signature the code has and a usage quoted from the codebase.","href":"/docs/reference/attributes-ssr"},{"slug":"attributes-tenancy","title":"Tenancy attributes","summary":"Every attribute declared by `Tenancy`, with the signature the code has and a usage quoted from the codebase.","href":"/docs/reference/attributes-tenancy"},{"slug":"attributes-testing","title":"Testing attributes","summary":"Every attribute declared by `Testing`, with the signature the code has and a usage quoted from the codebase.","href":"/docs/reference/attributes-testing"},{"slug":"attributes-update","title":"Update attributes","summary":"Every attribute declared by `Update`, with the signature the code has and a usage quoted from the codebase.","href":"/docs/reference/attributes-update"},{"slug":"attributes-webhooks","title":"Webhooks attributes","summary":"Every attribute declared by `Webhooks`, with the signature the code has and a usage quoted from the codebase.","href":"/docs/reference/attributes-webhooks"},{"slug":"attributes-workflow","title":"Workflow attributes","summary":"Every attribute declared by `Workflow`, with the signature the code has and a usage quoted from the codebase.","href":"/docs/reference/attributes-workflow"},{"slug":"commands-ai","title":"ai commands","summary":"Every `ai` command, with the arguments and options the console actually defines.","href":"/docs/reference/commands-ai"},{"slug":"commands-cache","title":"cache commands","summary":"Every `cache` command, with the arguments and options the console actually defines.","href":"/docs/reference/commands-cache"},{"slug":"commands-contracts","title":"contracts commands","summary":"Every `contracts` command, with the arguments and options the console actually defines.","href":"/docs/reference/commands-contracts"},{"slug":"commands-demo","title":"demo commands","summary":"Every `demo` command, with the arguments and options the console actually defines.","href":"/docs/reference/commands-demo"},{"slug":"commands-dev","title":"dev commands","summary":"Every `dev` command, with the arguments and options the console actually defines.","href":"/docs/reference/commands-dev"},{"slug":"commands-docs","title":"docs commands","summary":"Every `docs` command, with the arguments and options the console actually defines.","href":"/docs/reference/commands-docs"},{"slug":"commands-general","title":"general commands","summary":"Every `general` command, with the arguments and options the console actually defines.","href":"/docs/reference/commands-general"},{"slug":"commands-ledger","title":"ledger commands","summary":"Every `ledger` command, with the arguments and options the console actually defines.","href":"/docs/reference/commands-ledger"},{"slug":"commands-lint","title":"lint commands","summary":"Every `lint` command, with the arguments and options the console actually defines.","href":"/docs/reference/commands-lint"},{"slug":"commands-local-app","title":"local-app commands","summary":"Every `local-app` command, with the arguments and options the console actually defines.","href":"/docs/reference/commands-local-app"},{"slug":"commands-local-domain","title":"local-domain commands","summary":"Every `local-domain` command, with the arguments and options the console actually defines.","href":"/docs/reference/commands-local-domain"},{"slug":"commands-local-router","title":"local-router commands","summary":"Every `local-router` command, with the arguments and options the console actually defines.","href":"/docs/reference/commands-local-router"},{"slug":"commands-logs","title":"logs commands","summary":"Every `logs` command, with the arguments and options the console actually defines.","href":"/docs/reference/commands-logs"},{"slug":"commands-mail","title":"mail commands","summary":"Every `mail` command, with the arguments and options the console actually defines.","href":"/docs/reference/commands-mail"},{"slug":"commands-make","title":"make commands","summary":"Every `make` command, with the arguments and options the console actually defines.","href":"/docs/reference/commands-make"},{"slug":"commands-media","title":"media commands","summary":"Every `media` command, with the arguments and options the console actually defines.","href":"/docs/reference/commands-media"},{"slug":"commands-openapi","title":"openapi commands","summary":"Every `openapi` command, with the arguments and options the console actually defines.","href":"/docs/reference/commands-openapi"},{"slug":"commands-orm","title":"orm commands","summary":"Every `orm` command, with the arguments and options the console actually defines.","href":"/docs/reference/commands-orm"},{"slug":"commands-os","title":"os commands","summary":"Every `os` command, with the arguments and options the console actually defines.","href":"/docs/reference/commands-os"},{"slug":"commands-platform-ui","title":"platform-ui commands","summary":"Every `platform-ui` command, with the arguments and options the console actually defines.","href":"/docs/reference/commands-platform-ui"},{"slug":"commands-playground","title":"playground commands","summary":"Every `playground` command, with the arguments and options the console actually defines.","href":"/docs/reference/commands-playground"},{"slug":"commands-prompt","title":"prompt commands","summary":"Every `prompt` command, with the arguments and options the console actually defines.","href":"/docs/reference/commands-prompt"},{"slug":"commands-queue","title":"queue commands","summary":"Every `queue` command, with the arguments and options the console actually defines.","href":"/docs/reference/commands-queue"},{"slug":"commands-registry","title":"registry commands","summary":"Every `registry` command, with the arguments and options the console actually defines.","href":"/docs/reference/commands-registry"},{"slug":"commands-routes","title":"routes commands","summary":"Every `routes` command, with the arguments and options the console actually defines.","href":"/docs/reference/commands-routes"},{"slug":"commands-scaffold","title":"scaffold commands","summary":"Every `scaffold` command, with the arguments and options the console actually defines.","href":"/docs/reference/commands-scaffold"},{"slug":"commands-scheduler","title":"scheduler commands","summary":"Every `scheduler` command, with the arguments and options the console actually defines.","href":"/docs/reference/commands-scheduler"},{"slug":"commands-server","title":"server commands","summary":"Every `server` command, with the arguments and options the console actually defines.","href":"/docs/reference/commands-server"},{"slug":"commands-sitemap","title":"sitemap commands","summary":"Every `sitemap` command, with the arguments and options the console actually defines.","href":"/docs/reference/commands-sitemap"},{"slug":"commands-skins","title":"skins commands","summary":"Every `skins` command, with the arguments and options the console actually defines.","href":"/docs/reference/commands-skins"},{"slug":"commands-system","title":"system commands","summary":"Every `system` command, with the arguments and options the console actually defines.","href":"/docs/reference/commands-system"},{"slug":"commands-tasks","title":"tasks commands","summary":"Every `tasks` command, with the arguments and options the console actually defines.","href":"/docs/reference/commands-tasks"},{"slug":"commands-tenant","title":"tenant commands","summary":"Every `tenant` command, with the arguments and options the console actually defines.","href":"/docs/reference/commands-tenant"},{"slug":"commands-test","title":"test commands","summary":"Every `test` command, with the arguments and options the console actually defines.","href":"/docs/reference/commands-test"},{"slug":"commands-theme","title":"theme commands","summary":"Every `theme` command, with the arguments and options the console actually defines.","href":"/docs/reference/commands-theme"},{"slug":"commands-ui-playground","title":"ui-playground commands","summary":"Every `ui-playground` command, with the arguments and options the console actually defines.","href":"/docs/reference/commands-ui-playground"},{"slug":"commands-update","title":"update commands","summary":"Every `update` command, with the arguments and options the console actually defines.","href":"/docs/reference/commands-update"},{"slug":"commands-weave","title":"weave commands","summary":"Every `weave` command, with the arguments and options the console actually defines.","href":"/docs/reference/commands-weave"},{"slug":"commands-webhook","title":"webhook commands","summary":"Every `webhook` command, with the arguments and options the console actually defines.","href":"/docs/reference/commands-webhook"},{"slug":"events","title":"Events","summary":"Every event the runtime routes, named by the listeners that subscribe to it.","href":"/docs/reference/events"}]},{"section":"rendering","documents":[{"slug":"philosophy","title":"SSR Philosophy","summary":"Semitexa SSR is one continuous rendering architecture: page, slots, deferred regions, live refresh, and interactive components stay inside one server-owned story.","href":"/docs/rendering/philosophy"},{"slug":"resource-dtos","title":"Resource DTOs","summary":"A Resource DTO is the one typed source of presentation data: handlers shape it once, templates consume it everywhere, and no view has to dissect random arrays.","href":"/docs/rendering/resource-dtos"},{"slug":"slots","title":"Slot Resources","summary":"Each page region is its own resource pipeline with the same template system as the main page — no scattered partial glue, no mystery wiring.","href":"/docs/rendering/slots"},{"slug":"components","title":"Components","summary":"Reusable, attribute-registered UI components — discovered automatically from the classmap.","href":"/docs/rendering/components"},{"slug":"seo","title":"SEO","summary":"Set title, description, and Open Graph tags from your handler — no template hacks needed.","href":"/docs/rendering/seo"},{"slug":"assets","title":"Asset Pipeline","summary":"Declare assets with glob patterns in assets.json — served, versioned, and injected automatically.","href":"/docs/rendering/assets"},{"slug":"component-scripts","title":"Component Script Assets","summary":"A Semitexa SSR component can own its optional enhancement asset, so behavior travels with the component instead of leaking into page-level glue.","href":"/docs/rendering/component-scripts"},{"slug":"deferred-scripts","title":"Script Injection","summary":"Deferred blocks carry their own JS — injected once when the block arrives, never duplicated.","href":"/docs/rendering/deferred-scripts"},{"slug":"deferred","title":"Deferred Blocks","summary":"SSR renders the shell first, then expensive regions stream in as real HTML over SSE — no SPA handoff and no client-side page rebuild.","href":"/docs/rendering/deferred"},{"slug":"deferred-encapsulation","title":"Block Isolation","summary":"Two identical blocks on the same page run independently — scoped DOM, scoped JS, no conflicts.","href":"/docs/rendering/deferred-encapsulation"},{"slug":"deferred-live","title":"Live Widgets","summary":"A live slot can refresh itself on a timer while the page stays SSR-first — no SPA runtime and no handwritten polling layer.","href":"/docs/rendering/deferred-live"},{"slug":"reactive-report","title":"Reactive Report","summary":"Background work updates an SSR-first slot in place, so the UI feels live without falling back to SPA state orchestration.","href":"/docs/rendering/reactive-report"},{"slug":"reactive-import","title":"Reactive Import","summary":"Background batches keep moving, and the page reflects server progress as live HTML instead of a client-managed progress app.","href":"/docs/rendering/reactive-import"},{"slug":"reactive-analytics","title":"Reactive Analytics","summary":"Independent analytics jobs can light up one dashboard progressively, while the page stays server-rendered from the first byte.","href":"/docs/rendering/reactive-analytics"},{"slug":"reactive-ai","title":"Reactive AI Task","summary":"Submit a task and watch the AI pipeline stages reveal one by one as the cron job processes it.","href":"/docs/rendering/reactive-ai"},{"slug":"ui-primitives","title":"UI Primitives","summary":"The atomic ui=\"...\" vocabulary -- button, input, label, field-shell, surface, badge -- and the attribute-driven runtime behind it.","href":"/docs/rendering/ui-primitives"},{"slug":"ui-composition","title":"UI Composition: UiPart and UiSlot","summary":"How a component declares the primitives it is made of, how part props resolve, and how bind, slots and inputProps behave.","href":"/docs/rendering/ui-composition"},{"slug":"ui-events","title":"UI Events and Transport","summary":"Declaring events with UiOn, the signed render-time manifest, the capture-only frontend runtime, the HTTP dispatch endpoint and the SSE push channel.","href":"/docs/rendering/ui-events"},{"slug":"ui-forms","title":"UI Forms","summary":"Composing platform.form, the authoritative submit pipeline, per-field signed projection and the playground.","href":"/docs/rendering/ui-forms"},{"slug":"ui-grammar","title":"UI Grammar Reference","summary":"The attribute grammar a component author writes: what each attribute means and where it is allowed.","href":"/docs/rendering/ui-grammar"},{"slug":"ui-ssr-integration","title":"UI and SSR Integration","summary":"How platform-ui primitives and components sit on top of the SSR module.","href":"/docs/rendering/ui-ssr-integration"},{"slug":"template-cache","title":"Twig Template Cache","summary":"How the Twig cache behaves under long-running workers and when you need to clear it.","href":"/docs/rendering/template-cache"}]},{"section":"routing","documents":[{"slug":"basic","title":"Basic Route","summary":"Define a route with one access attribute on the payload — no XML, no YAML, no config files.","href":"/docs/routing/basic"},{"slug":"adding-routes","title":"Adding Pages and Routes","summary":"Creating a module and its first route end to end: JSON and HTML responses, where each class goes, how discovery finds it, a custom 404, and the usual mistakes.","href":"/docs/routing/adding-routes"},{"slug":"parameterized","title":"Parameterized Route","summary":"Path parameters with regex constraints, how the hydrator injects them, and why a default does not make a segment optional.","href":"/docs/routing/parameterized"},{"slug":"env-route-override","title":"Env Route Override","summary":"Keep the payload as the route source of truth while allowing operations to remap the public URL through .env.","href":"/docs/routing/env-route-override"},{"slug":"payload-shield","title":"Payload As A Shield","summary":"Hydration happens before the handler, and each setter owns the normalization and guard logic for its own field.","href":"/docs/routing/payload-shield"},{"slug":"payload-parts","title":"Payload Parts","summary":"One module owns the route, another module can extend the same payload contract without forking or reopening the base class.","href":"/docs/routing/payload-parts"},{"slug":"content-negotiation","title":"Content Negotiation","summary":"One endpoint, multiple response formats — automatically.","href":"/docs/routing/content-negotiation"},{"slug":"public-endpoint","title":"Public Payload","summary":"Anonymous endpoints opt in explicitly with the public access attribute. Every other payload requires authentication.","href":"/docs/routing/public-endpoint"},{"slug":"debugging","title":"Debugging Routes","summary":"Three commands that answer why a route is not matching, what it resolves to, and which template finally renders it.","href":"/docs/routing/debugging"}]},{"section":"runtime","documents":[{"slug":"state-lifecycle","title":"Runtime State Lifecycle","summary":"Per-request, per-worker, persistent, and test-only state — the Swoole-aware taxonomy that decides which caches reset between requests, which survive across requests, and which only reset when a test explicitly asks.","href":"/docs/runtime/state-lifecycle"},{"slug":"sessions-and-cookies","title":"Sessions and Cookies","summary":"The session contract and its Swoole Table storage, typed session segments, flash messages, and reading and writing cookies.","href":"/docs/runtime/sessions-and-cookies"},{"slug":"request-context","title":"Request Context: Tenant, Auth, Locale","summary":"Reaching the per-request tenant, auth and locale -- through the request-scoped container or statically -- and when each is still at its default.","href":"/docs/runtime/request-context"}]},{"section":"testing","documents":[{"slug":"payload-contracts","title":"Payload Contract Testing","summary":"Run one project-level contract suite through the canonical test runner and let strategy profiles verify payload boundaries without hand-writing repetitive negative cases.","href":"/docs/testing/payload-contracts"}]},{"section":"validation","documents":[{"slug":"core-validators","title":"Core Validators","summary":"Trait-based validation primitives covering presence, type, string, format, numeric, datetime, choice, collection, comparison, conditional, composite, and domain rules — composed into payload `validate()` methods that the framework runs automatically before handlers.","href":"/docs/validation/core-validators"},{"slug":"ui-field-validation","title":"UI Field Validation","summary":"The server-side rules DSL for platform-ui fields, including cross-field rules such as sameAsField.","href":"/docs/validation/ui-field-validation"},{"slug":"payload-validation","title":"Payload Validation","summary":"Where validation sits in the pipeline, how payload rules and helpers are written, hydration, the failure response, and session and cookie payloads.","href":"/docs/validation/payload-validation"}]}],"doc_title":"Core attributes","doc_summary":"Every attribute declared by `Core`, with the signature the code has and a usage quoted from the codebase.","doc_html":"<article class=\"sx-docs-fragment\" data-doc-id=\"reference/attributes-core\" data-doc-locale=\"en\">\n<!-- Generated by `bin/semitexa docs:reference:generate` — do not edit by hand. -->\n<h1>Core attributes</h1>\n<p>Every attribute declared by <code>Core</code>, with the signature the code has and a usage quoted from the codebase.</p>\n<h2><code>#[AsCommand]</code></h2>\n<p><code>Semitexa\\Core\\Attribute\\AsCommand</code></p>\n<p>Applies to: class</p>\n<table>\n<thead>\n<tr>\n<th>parameter</th>\n<th>type</th>\n<th>required</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>name</code></td>\n<td><code>string</code></td>\n<td>yes</td>\n</tr>\n<tr>\n<td><code>description</code></td>\n<td><code>string</code></td>\n<td>no</td>\n</tr>\n<tr>\n<td><code>aliases</code></td>\n<td><code>array</code></td>\n<td>no</td>\n</tr>\n<tr>\n<td><code>arguments</code></td>\n<td><code>array</code></td>\n<td>no</td>\n</tr>\n<tr>\n<td><code>options</code></td>\n<td><code>array</code></td>\n<td>no</td>\n</tr>\n<tr>\n<td><code>base</code></td>\n<td><code>string</code></td>\n<td>no</td>\n</tr>\n</tbody>\n</table>\n<pre><code class=\"language-php\">#[AsCommand(name: 'seed:demo-data', description: 'Seed demo data for local environments')]\n#[AsAiSkill(\n    allowed: 'env::AI_ENABLE_SEED_SKILL::false',\n    summary: 'Seed local demo data when the project explicitly allows this skill.',\n    useWhen: 'User wants to seed local demo fixtures in a safe non-production context.',\n    avoidWhen: 'Production data is involved or the env flag is not enabled.',\n    riskLevel: AiRiskLevel::High,\n    confirmation: AiConfirmationMode::Always,\n    argumentPolicy: 'allowlisted',\n    exposeArguments: ['tenant', 'force'],\n)]\nfinal class SeedDemoDataCommand extends Command\n</code></pre>\n<p>— <code>vendor/semitexa/demo/resources/examples/Llm/EnvControlledSkill.example.php</code></p>\n<h2><code>#[AsDiscoveryContributor]</code></h2>\n<p><code>Semitexa\\Core\\Attribute\\AsDiscoveryContributor</code></p>\n<p>Applies to: class</p>\n<table>\n<thead>\n<tr>\n<th>parameter</th>\n<th>type</th>\n<th>required</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>priority</code></td>\n<td><code>int</code></td>\n<td>no</td>\n</tr>\n<tr>\n<td><code>doc</code></td>\n<td><code>string</code></td>\n<td>no</td>\n</tr>\n</tbody>\n</table>\n<pre><code class=\"language-php\">#[AsDiscoveryContributor(priority: 200)]\nfinal class DataProviderContributor implements DiscoveryContributor\n</code></pre>\n<p>— <code>vendor/semitexa/ssr/src/Application/Service/Discovery/DataProviderContributor.php</code></p>\n<h2><code>#[AsDoctorCheck]</code></h2>\n<p><code>Semitexa\\Core\\Attribute\\AsDoctorCheck</code></p>\n<p>Applies to: class</p>\n<table>\n<thead>\n<tr>\n<th>parameter</th>\n<th>type</th>\n<th>required</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>name</code></td>\n<td><code>string</code></td>\n<td>yes</td>\n</tr>\n<tr>\n<td><code>package</code></td>\n<td><code>string</code></td>\n<td>no</td>\n</tr>\n</tbody>\n</table>\n<pre><code class=\"language-php\">#[AsDoctorCheck(name: 'cache.driver', package: 'semitexa/cache')]\nfinal class CacheDriverDoctorCheck implements DoctorCheckInterface\n</code></pre>\n<p>— <code>vendor/semitexa/cache/src/Application/Service/CacheDriverDoctorCheck.php</code></p>\n<h2><code>#[AsEvent]</code></h2>\n<p><code>Semitexa\\Core\\Attribute\\AsEvent</code></p>\n<p>Applies to: class</p>\n<p>Takes no arguments.</p>\n<pre><code class=\"language-php\">#[AsEvent]\nfinal class DemoItemCreated\n</code></pre>\n<p>— <code>vendor/semitexa/demo/resources/examples/Async/SyncEvents/DemoItemCreated.example.php</code></p>\n<h2><code>#[AsEventListener]</code></h2>\n<p><code>Semitexa\\Core\\Attribute\\AsEventListener</code></p>\n<p>Applies to: class</p>\n<table>\n<thead>\n<tr>\n<th>parameter</th>\n<th>type</th>\n<th>required</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>event</code></td>\n<td><code>string</code></td>\n<td>yes</td>\n</tr>\n<tr>\n<td><code>execution</code></td>\n<td>`Semitexa\\Core\\Event\\EventExecution</td>\n<td>string`</td>\n</tr>\n<tr>\n<td><code>transport</code></td>\n<td><code>string</code></td>\n<td>no</td>\n</tr>\n<tr>\n<td><code>queue</code></td>\n<td><code>string</code></td>\n<td>no</td>\n</tr>\n<tr>\n<td><code>priority</code></td>\n<td><code>int</code></td>\n<td>no</td>\n</tr>\n</tbody>\n</table>\n<pre><code class=\"language-php\">#[AsEventListener(event: DemoItemCreated::class, execution: EventExecution::Async)]\nfinal class DemoNotificationListener\n</code></pre>\n<p>— <code>vendor/semitexa/demo/resources/examples/Async/Deferred/DemoNotificationListener.example.php</code></p>\n<h2><code>#[AsPayloadHandler]</code></h2>\n<p><code>Semitexa\\Core\\Attribute\\AsPayloadHandler</code></p>\n<p>Applies to: class</p>\n<table>\n<thead>\n<tr>\n<th>parameter</th>\n<th>type</th>\n<th>required</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>payload</code></td>\n<td><code>string</code></td>\n<td>yes</td>\n</tr>\n<tr>\n<td><code>resource</code></td>\n<td><code>string</code></td>\n<td>yes</td>\n</tr>\n<tr>\n<td><code>execution</code></td>\n<td>`Semitexa\\Core\\Queue\\HandlerExecution</td>\n<td>string</td>\n</tr>\n<tr>\n<td><code>transport</code></td>\n<td><code>string</code></td>\n<td>no</td>\n</tr>\n<tr>\n<td><code>queue</code></td>\n<td><code>string</code></td>\n<td>no</td>\n</tr>\n<tr>\n<td><code>priority</code></td>\n<td><code>int</code></td>\n<td>no</td>\n</tr>\n<tr>\n<td><code>maxRetries</code></td>\n<td><code>int</code></td>\n<td>no</td>\n</tr>\n<tr>\n<td><code>retryDelay</code></td>\n<td><code>int</code></td>\n<td>no</td>\n</tr>\n<tr>\n<td><code>doc</code></td>\n<td><code>string</code></td>\n<td>no</td>\n</tr>\n</tbody>\n</table>\n<pre><code class=\"language-php\">#[AsPayloadHandler(payload: ApiErrorTriggerPayload::class, resource: ErrorEnvelopeResource::class)]\nfinal class ApiErrorTriggerHandler implements TypedHandlerInterface\n</code></pre>\n<p>— <code>vendor/semitexa/demo/resources/examples/Api/Errors/ApiErrorTriggerHandler.example.php</code></p>\n<h2><code>#[AsPayloadPart]</code></h2>\n<p><code>Semitexa\\Core\\Attribute\\AsPayloadPart</code></p>\n<p>Applies to: class</p>\n<table>\n<thead>\n<tr>\n<th>parameter</th>\n<th>type</th>\n<th>required</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>base</code></td>\n<td><code>string</code></td>\n<td>yes</td>\n</tr>\n<tr>\n<td><code>doc</code></td>\n<td><code>string</code></td>\n<td>no</td>\n</tr>\n</tbody>\n</table>\n<pre><code class=\"language-php\">#[AsPayloadPart(base: SearchPayload::class)]\ntrait SearchTrackingPart\n</code></pre>\n<p>— <code>vendor/semitexa/demo/resources/examples/Routing/PayloadParts/SearchTrackingPart.example.php</code></p>\n<h2><code>#[AsPipelineListener]</code></h2>\n<p><code>Semitexa\\Core\\Attribute\\AsPipelineListener</code></p>\n<p>Applies to: class</p>\n<table>\n<thead>\n<tr>\n<th>parameter</th>\n<th>type</th>\n<th>required</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>phase</code></td>\n<td><code>string</code></td>\n<td>yes</td>\n</tr>\n<tr>\n<td><code>priority</code></td>\n<td><code>int</code></td>\n<td>no</td>\n</tr>\n</tbody>\n</table>\n<pre><code class=\"language-php\">#[AsPipelineListener(phase: AuthCheck::class, priority: 0)]\nfinal class AuthorizationListener implements PipelineListenerInterface\n</code></pre>\n<p>— <code>vendor/semitexa/authorization/src/Pipeline/AuthorizationListener.php</code></p>\n<h2><code>#[AsPublicPayload]</code></h2>\n<p><code>Semitexa\\Core\\Attribute\\AsPublicPayload</code></p>\n<p>Applies to: class</p>\n<table>\n<thead>\n<tr>\n<th>parameter</th>\n<th>type</th>\n<th>required</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>doc</code></td>\n<td><code>string</code></td>\n<td>no</td>\n</tr>\n<tr>\n<td><code>base</code></td>\n<td><code>string</code></td>\n<td>no</td>\n</tr>\n<tr>\n<td><code>overrides</code></td>\n<td><code>string</code></td>\n<td>no</td>\n</tr>\n<tr>\n<td><code>path</code></td>\n<td><code>string</code></td>\n<td>no</td>\n</tr>\n<tr>\n<td><code>methods</code></td>\n<td><code>array</code></td>\n<td>no</td>\n</tr>\n<tr>\n<td><code>name</code></td>\n<td><code>string</code></td>\n<td>no</td>\n</tr>\n<tr>\n<td><code>requirements</code></td>\n<td><code>array</code></td>\n<td>no</td>\n</tr>\n<tr>\n<td><code>defaults</code></td>\n<td><code>array</code></td>\n<td>no</td>\n</tr>\n<tr>\n<td><code>options</code></td>\n<td><code>array</code></td>\n<td>no</td>\n</tr>\n<tr>\n<td><code>tags</code></td>\n<td><code>array</code></td>\n<td>no</td>\n</tr>\n<tr>\n<td><code>responseWith</code></td>\n<td><code>string</code></td>\n<td>no</td>\n</tr>\n<tr>\n<td><code>consumes</code></td>\n<td><code>array</code></td>\n<td>no</td>\n</tr>\n<tr>\n<td><code>produces</code></td>\n<td><code>array</code></td>\n<td>no</td>\n</tr>\n<tr>\n<td><code>transport</code></td>\n<td><code>Semitexa\\Core\\Attribute\\TransportType</code></td>\n<td>no</td>\n</tr>\n<tr>\n<td><code>renderProfile</code></td>\n<td>`Semitexa\\Core\\Resource\\RenderProfile</td>\n<td>array</td>\n</tr>\n<tr>\n<td><code>responsesByProfile</code></td>\n<td><code>array</code></td>\n<td>no</td>\n</tr>\n<tr>\n<td><code>sseGateModel</code></td>\n<td><code>Semitexa\\Core\\Attribute\\SseGateModel</code></td>\n<td>no</td>\n</tr>\n</tbody>\n</table>\n<pre><code class=\"language-php\">#[AsPublicPayload(\n    path: '/api/demo/errors/{scenario}',\n    methods: ['GET'],\n    responseWith: ErrorEnvelopeResource::class,\n    produces: ['application/json'],\n)]\nfinal class ApiErrorTriggerPayload\n</code></pre>\n<p>— <code>vendor/semitexa/demo/resources/examples/Api/Errors/ApiErrorTriggerPayload.example.php</code></p>\n<h2><code>#[AsResource]</code></h2>\n<p><code>Semitexa\\Core\\Attribute\\AsResource</code></p>\n<p>Applies to: class</p>\n<table>\n<thead>\n<tr>\n<th>parameter</th>\n<th>type</th>\n<th>required</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>handle</code></td>\n<td><code>string</code></td>\n<td>no</td>\n</tr>\n<tr>\n<td><code>doc</code></td>\n<td><code>string</code></td>\n<td>no</td>\n</tr>\n<tr>\n<td><code>base</code></td>\n<td><code>string</code></td>\n<td>no</td>\n</tr>\n<tr>\n<td><code>context</code></td>\n<td><code>array</code></td>\n<td>no</td>\n</tr>\n<tr>\n<td><code>format</code></td>\n<td><code>Semitexa\\Core\\Http\\Response\\ResponseFormat</code></td>\n<td>no</td>\n</tr>\n<tr>\n<td><code>renderer</code></td>\n<td><code>string</code></td>\n<td>no</td>\n</tr>\n<tr>\n<td><code>produces</code></td>\n<td><code>array</code></td>\n<td>no</td>\n</tr>\n<tr>\n<td><code>template</code></td>\n<td><code>string</code></td>\n<td>no</td>\n</tr>\n</tbody>\n</table>\n<pre><code class=\"language-php\">#[AsResource(\n    handle: 'product_showcase',\n    template: '@project/catalog/pages/product-show.html.twig',\n)]\nfinal class ProductShowcaseResource extends HtmlResponse\n</code></pre>\n<p>— <code>vendor/semitexa/demo/resources/examples/GetStarted/ProductShowcaseResource.example.php</code></p>\n<h2><code>#[AsResourcePart]</code></h2>\n<p><code>Semitexa\\Core\\Attribute\\AsResourcePart</code></p>\n<p>Applies to: class</p>\n<table>\n<thead>\n<tr>\n<th>parameter</th>\n<th>type</th>\n<th>required</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>base</code></td>\n<td><code>string</code></td>\n<td>yes</td>\n</tr>\n</tbody>\n</table>\n<p><em>No usage found in this installation.</em></p>\n<h2><code>#[AsServerLifecycleListener]</code></h2>\n<p><code>Semitexa\\Core\\Attribute\\AsServerLifecycleListener</code></p>\n<p>Applies to: class</p>\n<table>\n<thead>\n<tr>\n<th>parameter</th>\n<th>type</th>\n<th>required</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>phase</code></td>\n<td><code>string</code></td>\n<td>yes</td>\n</tr>\n<tr>\n<td><code>priority</code></td>\n<td><code>int</code></td>\n<td>no</td>\n</tr>\n<tr>\n<td><code>requiresContainer</code></td>\n<td><code>bool</code></td>\n<td>no</td>\n</tr>\n</tbody>\n</table>\n<pre><code class=\"language-php\">#[AsServerLifecycleListener(\n    phase: ServerLifecyclePhase::WorkerStartFinalize-&gt;value,\n    priority: 0,\n    requiresContainer: true,\n)]\nfinal class WarmResourceMetadataListener implements ServerLifecycleListenerInterface\n</code></pre>\n<p>— <code>vendor/semitexa/core/src/Resource/Lifecycle/WarmResourceMetadataListener.php</code></p>\n<h2><code>#[AsService]</code></h2>\n<p><code>Semitexa\\Core\\Attribute\\AsService</code></p>\n<p>Applies to: class</p>\n<p>Takes no arguments.</p>\n<pre><code class=\"language-php\">#[AsService]\n#[ExecutionScoped]\n#[AsAuthHandler(priority: -20)]\nfinal class GoogleSessionAuthHandler implements AuthHandlerInterface\n</code></pre>\n<p>— <code>vendor/semitexa/demo/src/Application/Handler/PayloadHandler/Auth/GoogleSessionAuthHandler.php</code></p>\n<h2><code>#[Capability]</code></h2>\n<p><code>Semitexa\\Core\\Attribute\\Capability</code></p>\n<p>Applies to: class. Repeatable.</p>\n<table>\n<thead>\n<tr>\n<th>parameter</th>\n<th>type</th>\n<th>required</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>id</code></td>\n<td><code>string</code></td>\n<td>yes</td>\n</tr>\n<tr>\n<td><code>summary</code></td>\n<td><code>string</code></td>\n<td>yes</td>\n</tr>\n<tr>\n<td><code>useWhen</code></td>\n<td><code>string</code></td>\n<td>yes</td>\n</tr>\n<tr>\n<td><code>avoidWhen</code></td>\n<td><code>string</code></td>\n<td>yes</td>\n</tr>\n<tr>\n<td><code>replaces</code></td>\n<td><code>array</code></td>\n<td>yes</td>\n</tr>\n<tr>\n<td><code>seeAlso</code></td>\n<td><code>string</code></td>\n<td>no</td>\n</tr>\n</tbody>\n</table>\n<pre><code class=\"language-php\">#[Capability(\n    id: 'demo.showcase',\n    summary: 'The official showcase application: framework features as running pages, next to the source that produces them.',\n    useWhen: 'A feature has to be seen working before it is adopted, or a convention needs a reference implementation to copy from.',\n    avoidWhen: 'A production deployment. It is a teaching surface, with routes and fixtures nobody should ship to end users.',\n    replaces: [\n        'a scratch module written to try a feature out and then left in the project',\n        'reading a package test suite to work out how the feature is meant to be assembled',\n    ],\n)]\nfinal class Capabilities\n</code></pre>\n<p>— <code>vendor/semitexa/demo/src/Capabilities.php</code></p>\n<h2><code>#[Config]</code></h2>\n<p><code>Semitexa\\Core\\Attribute\\Config</code></p>\n<p>Applies to: property</p>\n<table>\n<thead>\n<tr>\n<th>parameter</th>\n<th>type</th>\n<th>required</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>env</code></td>\n<td><code>string</code></td>\n<td>no</td>\n</tr>\n<tr>\n<td><code>default</code></td>\n<td>`BackedEnum</td>\n<td>string</td>\n</tr>\n</tbody>\n</table>\n<pre><code class=\"language-php\">    #[Config(env: 'CACHE_DRIVER', default: 'array')]\n    protected string $driver;\n</code></pre>\n<p>— <code>vendor/semitexa/cache/src/Application/Service/CacheManager.php</code></p>\n<h2><code>#[CsrfExempt]</code></h2>\n<p><code>Semitexa\\Core\\Csrf\\Attribute\\CsrfExempt</code></p>\n<p>Applies to: class</p>\n<p>Takes no arguments.</p>\n<p><em>No usage found in this installation.</em></p>\n<h2><code>#[ExecutionScoped]</code></h2>\n<p><code>Semitexa\\Core\\Attribute\\ExecutionScoped</code></p>\n<p>Applies to: class</p>\n<p>Takes no arguments.</p>\n<pre><code class=\"language-php\">#[ExecutionScoped]\n#[AsAuthHandler(priority: -20)]\nfinal class GoogleSessionAuthHandler implements AuthHandlerInterface\n</code></pre>\n<p>— <code>vendor/semitexa/demo/src/Application/Handler/PayloadHandler/Auth/GoogleSessionAuthHandler.php</code></p>\n<h2><code>#[HandlerProvidesResourceIncludes]</code></h2>\n<p><code>Semitexa\\Core\\Resource\\Attribute\\HandlerProvidesResourceIncludes</code></p>\n<p>Applies to: class</p>\n<table>\n<thead>\n<tr>\n<th>parameter</th>\n<th>type</th>\n<th>required</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>resource</code></td>\n<td><code>string</code></td>\n<td>yes</td>\n</tr>\n<tr>\n<td><code>tokens</code></td>\n<td><code>array</code></td>\n<td>yes</td>\n</tr>\n</tbody>\n</table>\n<p><em>No usage found in this installation.</em></p>\n<h2><code>#[InjectAsFactory]</code></h2>\n<p><code>Semitexa\\Core\\Attribute\\InjectAsFactory</code></p>\n<p>Applies to: property</p>\n<p>Takes no arguments.</p>\n<pre><code class=\"language-php\">    #[InjectAsFactory]\n    protected \\Closure $mailerFactory;\n</code></pre>\n<p>— <code>vendor/semitexa/demo/resources/examples/Container/Factory/FactoryInjectionHandler.example.php</code></p>\n<h2><code>#[InjectAsMutable]</code></h2>\n<p><code>Semitexa\\Core\\Attribute\\InjectAsMutable</code></p>\n<p>Applies to: property</p>\n<table>\n<thead>\n<tr>\n<th>parameter</th>\n<th>type</th>\n<th>required</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>optional</code></td>\n<td><code>bool</code></td>\n<td>no</td>\n</tr>\n</tbody>\n</table>\n<pre><code class=\"language-php\">    #[InjectAsMutable]\n    protected AuthContextInterface $auth;\n</code></pre>\n<p>— <code>vendor/semitexa/demo/resources/examples/Auth/Session/AccountDashboardHandler.example.php</code></p>\n<h2><code>#[InjectAsReadonly]</code></h2>\n<p><code>Semitexa\\Core\\Attribute\\InjectAsReadonly</code></p>\n<p>Applies to: property</p>\n<table>\n<thead>\n<tr>\n<th>parameter</th>\n<th>type</th>\n<th>required</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>optional</code></td>\n<td><code>bool</code></td>\n<td>no</td>\n</tr>\n</tbody>\n</table>\n<pre><code class=\"language-php\">    #[InjectAsReadonly]\n    protected SchemaRegistryInterface $schemaRegistry;\n</code></pre>\n<p>— <code>vendor/semitexa/demo/resources/examples/Api/Schema/ApiSchemaDiscoveryHandler.example.php</code></p>\n<h2><code>#[InternalAttribute]</code></h2>\n<p><code>Semitexa\\Core\\Attribute\\InternalAttribute</code></p>\n<p>Applies to: class</p>\n<table>\n<thead>\n<tr>\n<th>parameter</th>\n<th>type</th>\n<th>required</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>reason</code></td>\n<td><code>string</code></td>\n<td>yes</td>\n</tr>\n</tbody>\n</table>\n<p><em>No usage found in this installation.</em></p>\n<h2><code>#[LiveFilterParam]</code></h2>\n<p><code>Semitexa\\Core\\Attribute\\LiveFilterParam</code></p>\n<p>Applies to: property, parameter</p>\n<p>Takes no arguments.</p>\n<pre><code class=\"language-php\">    #[LiveFilterParam]\n    protected ?string $q = null;\n</code></pre>\n<p>— <code>vendor/semitexa/core/tests/Unit/Http/PayloadMetadataReflectorTest.php</code></p>\n<h2><code>#[PathParam]</code></h2>\n<p><code>Semitexa\\Core\\Request\\Attribute\\PathParam</code></p>\n<p>Applies to: property</p>\n<table>\n<thead>\n<tr>\n<th>parameter</th>\n<th>type</th>\n<th>required</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>name</code></td>\n<td><code>string</code></td>\n<td>yes</td>\n</tr>\n</tbody>\n</table>\n<p><em>No usage found in this installation.</em></p>\n<h2><code>#[ResolveWith]</code></h2>\n<p><code>Semitexa\\Core\\Resource\\Attribute\\ResolveWith</code></p>\n<p>Applies to: property</p>\n<table>\n<thead>\n<tr>\n<th>parameter</th>\n<th>type</th>\n<th>required</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>resolverClass</code></td>\n<td><code>string</code></td>\n<td>yes</td>\n</tr>\n</tbody>\n</table>\n<pre><code class=\"language-php\">        #[ResolveWith(CustomerProfileResolver::class)]\n        public ?ResourceRef $profile,\n</code></pre>\n<p>— <code>vendor/semitexa/api/tests/Fixtures/Customer/CustomerResource.php</code></p>\n<h2><code>#[ResourceField]</code></h2>\n<p><code>Semitexa\\Core\\Resource\\Attribute\\ResourceField</code></p>\n<p>Applies to: property</p>\n<table>\n<thead>\n<tr>\n<th>parameter</th>\n<th>type</th>\n<th>required</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>description</code></td>\n<td><code>string</code></td>\n<td>no</td>\n</tr>\n<tr>\n<td><code>deprecated</code></td>\n<td><code>bool</code></td>\n<td>no</td>\n</tr>\n</tbody>\n</table>\n<pre><code class=\"language-php\">        #[ResourceField]\n        public string $city,\n</code></pre>\n<p>— <code>vendor/semitexa/api/tests/Fixtures/Customer/AddressResource.php</code></p>\n<h2><code>#[ResourceId]</code></h2>\n<p><code>Semitexa\\Core\\Resource\\Attribute\\ResourceId</code></p>\n<p>Applies to: property</p>\n<p>Takes no arguments.</p>\n<pre><code class=\"language-php\">        #[ResourceId]\n        public string $id,\n</code></pre>\n<p>— <code>vendor/semitexa/api/tests/Fixtures/Customer/AddressResource.php</code></p>\n<h2><code>#[ResourceListOf]</code></h2>\n<p><code>Semitexa\\Core\\Resource\\Attribute\\ResourceListOf</code></p>\n<p>Applies to: property</p>\n<table>\n<thead>\n<tr>\n<th>parameter</th>\n<th>type</th>\n<th>required</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>target</code></td>\n<td><code>string</code></td>\n<td>yes</td>\n</tr>\n<tr>\n<td><code>description</code></td>\n<td><code>string</code></td>\n<td>no</td>\n</tr>\n</tbody>\n</table>\n<pre><code class=\"language-php\">        #[ResourceListOf(target: AddressResource::class)]\n        public array $tags = [],\n</code></pre>\n<p>— <code>vendor/semitexa/core/tests/Unit/Resource/Fixtures/CustomerResource.php</code></p>\n<h2><code>#[ResourceObject]</code></h2>\n<p><code>Semitexa\\Core\\Resource\\Attribute\\ResourceObject</code></p>\n<p>Applies to: class</p>\n<table>\n<thead>\n<tr>\n<th>parameter</th>\n<th>type</th>\n<th>required</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>type</code></td>\n<td><code>string</code></td>\n<td>yes</td>\n</tr>\n<tr>\n<td><code>description</code></td>\n<td><code>string</code></td>\n<td>no</td>\n</tr>\n<tr>\n<td><code>deprecated</code></td>\n<td><code>bool</code></td>\n<td>no</td>\n</tr>\n</tbody>\n</table>\n<pre><code class=\"language-php\">#[ResourceObject(type: 'address')]\nfinal readonly class AddressResource implements ResourceObjectInterface\n</code></pre>\n<p>— <code>vendor/semitexa/api/tests/Fixtures/Customer/AddressResource.php</code></p>\n<h2><code>#[ResourceRef]</code></h2>\n<p><code>Semitexa\\Core\\Resource\\Attribute\\ResourceRef</code></p>\n<p>Applies to: property</p>\n<table>\n<thead>\n<tr>\n<th>parameter</th>\n<th>type</th>\n<th>required</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>target</code></td>\n<td><code>string</code></td>\n<td>yes</td>\n</tr>\n<tr>\n<td><code>expandable</code></td>\n<td><code>bool</code></td>\n<td>no</td>\n</tr>\n<tr>\n<td><code>include</code></td>\n<td><code>string</code></td>\n<td>no</td>\n</tr>\n<tr>\n<td><code>href</code></td>\n<td><code>string</code></td>\n<td>no</td>\n</tr>\n<tr>\n<td><code>description</code></td>\n<td><code>string</code></td>\n<td>no</td>\n</tr>\n</tbody>\n</table>\n<p><em>No usage found in this installation.</em></p>\n<h2><code>#[ResourceRefList]</code></h2>\n<p><code>Semitexa\\Core\\Resource\\Attribute\\ResourceRefList</code></p>\n<p>Applies to: property</p>\n<table>\n<thead>\n<tr>\n<th>parameter</th>\n<th>type</th>\n<th>required</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>target</code></td>\n<td><code>string</code></td>\n<td>yes</td>\n</tr>\n<tr>\n<td><code>expandable</code></td>\n<td><code>bool</code></td>\n<td>no</td>\n</tr>\n<tr>\n<td><code>include</code></td>\n<td><code>string</code></td>\n<td>no</td>\n</tr>\n<tr>\n<td><code>href</code></td>\n<td><code>string</code></td>\n<td>no</td>\n</tr>\n<tr>\n<td><code>paginated</code></td>\n<td><code>bool</code></td>\n<td>no</td>\n</tr>\n<tr>\n<td><code>description</code></td>\n<td><code>string</code></td>\n<td>no</td>\n</tr>\n</tbody>\n</table>\n<p><em>No usage found in this installation.</em></p>\n<h2><code>#[ResourceUnion]</code></h2>\n<p><code>Semitexa\\Core\\Resource\\Attribute\\ResourceUnion</code></p>\n<p>Applies to: property</p>\n<table>\n<thead>\n<tr>\n<th>parameter</th>\n<th>type</th>\n<th>required</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>targets</code></td>\n<td><code>array</code></td>\n<td>yes</td>\n</tr>\n<tr>\n<td><code>discriminator</code></td>\n<td><code>string</code></td>\n<td>no</td>\n</tr>\n<tr>\n<td><code>list</code></td>\n<td><code>bool</code></td>\n<td>no</td>\n</tr>\n<tr>\n<td><code>expandable</code></td>\n<td><code>bool</code></td>\n<td>no</td>\n</tr>\n<tr>\n<td><code>include</code></td>\n<td><code>string</code></td>\n<td>no</td>\n</tr>\n<tr>\n<td><code>description</code></td>\n<td><code>string</code></td>\n<td>no</td>\n</tr>\n</tbody>\n</table>\n<pre><code class=\"language-php\">        #[ResourceUnion(\n            targets: [UserResource::class, BotResource::class],\n            list: false,\n            include: 'author',\n        )]\n        public ResourceRef $author = new ResourceRef(new ResourceIdentity('user', '0')),\n</code></pre>\n<p>— <code>vendor/semitexa/api/tests/Fixtures/Union/CommentResource.php</code></p>\n<h2><code>#[SatisfiesRepositoryContract]</code></h2>\n<p><code>Semitexa\\Core\\Attribute\\SatisfiesRepositoryContract</code></p>\n<p>Applies to: class</p>\n<table>\n<thead>\n<tr>\n<th>parameter</th>\n<th>type</th>\n<th>required</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>of</code></td>\n<td><code>string</code></td>\n<td>yes</td>\n</tr>\n</tbody>\n</table>\n<pre><code class=\"language-php\">#[SatisfiesRepositoryContract(of: DemoAiTaskRepositoryInterface::class)]\nfinal class DemoAiTaskRepository implements DemoAiTaskRepositoryInterface\n</code></pre>\n<p>— <code>vendor/semitexa/demo/src/Application/Db/MySQL/Repository/DemoAiTaskRepository.php</code></p>\n<h2><code>#[SatisfiesServiceContract]</code></h2>\n<p><code>Semitexa\\Core\\Attribute\\SatisfiesServiceContract</code></p>\n<p>Applies to: class. Repeatable.</p>\n<table>\n<thead>\n<tr>\n<th>parameter</th>\n<th>type</th>\n<th>required</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>of</code></td>\n<td><code>string</code></td>\n<td>yes</td>\n</tr>\n<tr>\n<td><code>factoryKey</code></td>\n<td><code>BackedEnum</code></td>\n<td>no</td>\n</tr>\n</tbody>\n</table>\n<pre><code class=\"language-php\">#[SatisfiesServiceContract(of: RouteMetadataResolverInterface::class)]\nfinal class ApiRouteMetadataResolver implements RouteMetadataResolverInterface\n</code></pre>\n<p>— <code>vendor/semitexa/api/src/Discovery/ApiRouteMetadataResolver.php</code></p>\n<h2><code>#[SessionSegment]</code></h2>\n<p><code>Semitexa\\Core\\Session\\Attribute\\SessionSegment</code></p>\n<p>Applies to: class</p>\n<table>\n<thead>\n<tr>\n<th>parameter</th>\n<th>type</th>\n<th>required</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>segment</code></td>\n<td><code>string</code></td>\n<td>yes</td>\n</tr>\n</tbody>\n</table>\n<pre><code class=\"language-php\">#[SessionSegment('browser_auth')]\nfinal class BrowserSessionSegment\n</code></pre>\n<p>— <code>vendor/semitexa/demo/resources/examples/Auth/Session/BrowserSessionSegment.example.php</code></p>\n<h2><code>#[WatchScopes]</code></h2>\n<p><code>Semitexa\\Core\\Attribute\\WatchScopes</code></p>\n<p>Applies to: class</p>\n<table>\n<thead>\n<tr>\n<th>parameter</th>\n<th>type</th>\n<th>required</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>scopes</code></td>\n<td><code>string</code></td>\n<td>no</td>\n</tr>\n</tbody>\n</table>\n<pre><code class=\"language-php\">#[WatchScopes('ui_playground_pings', 'playground_articles')]\nfinal class WatchScopedFeedPayloadFixture\n</code></pre>\n<p>— <code>vendor/semitexa/api/tests/Unit/Discovery/CollectionContractBlockContributorPhase4Test.php</code></p>\n</article>","section":"reference","__page_document_html_iri":"/docs/reference/attributes-core","__page_document_json_iri":"/docs/reference/attributes-core?_format=json","__page_alternates":[{"type":"application/json","href":"/docs/reference/attributes-core?_format=json"}]}