Add ephemeral (in-memory) template support#3
Conversation
Introduces EphemeralTemplate and EphemeralSection classes that implement the same Renderable and SchemaGeneratable interfaces as the Eloquent models but store everything in memory. Accessible via Schematic::ephemeral() or EphemeralTemplate::make(). Includes 34 new tests and README documentation. https://claude.ai/code/session_01Vpj7pFNHqQqvKDWmCm9GaT
There was a problem hiding this comment.
Pull request overview
This PR adds ephemeral (in-memory) templates/sections to Schematic, enabling runtime-defined templates that can generate JSON Schema and render/preview content without persisting anything to the database.
Changes:
- Introduces
EphemeralTemplateandEphemeralSectionclasses that mirror the persistedTemplate/SectionAPI for schema generation and rendering. - Adds
Schematic::ephemeral(...)(and facade annotation) as a convenience entry point for creating ephemeral templates. - Adds feature tests and README documentation describing ephemeral template usage.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/Feature/EphemeralTemplateTest.php | Adds feature tests for ephemeral template creation, section management, schema generation, rendering/preview, and “no DB queries” behavior. |
| tests/Feature/EphemeralSectionTest.php | Adds feature tests for ephemeral section creation, schema generation from fields, rendering/preview, and fluent builder methods. |
| src/Schematic.php | Adds ephemeral() factory method on the service for creating EphemeralTemplate instances. |
| src/Facades/Schematic.php | Updates facade docblock to include ephemeral(...) method signature. |
| src/Ephemeral/EphemeralTemplate.php | Implements in-memory template behavior: section storage, iteration/reordering, schema generation, rendering, and previewing. |
| src/Ephemeral/EphemeralSection.php | Implements in-memory section behavior: field definitions → schema generation, rendering/preview, and fluent mutation APIs. |
| README.md | Documents ephemeral templates and adds usage examples to README and table of contents. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| is_enabled: $enabled, | ||
| ); | ||
|
|
||
| $this->sections[] = $section; |
There was a problem hiding this comment.
Ephemeral templates currently allow adding multiple sections with the same slug (they’re appended to the in-memory array). Database-backed sections enforce uniqueness via the unique(template_id, slug) constraint, so this can create behavior mismatches (e.g., section('x') returns the first match while schema/render may include duplicates). Consider enforcing slug uniqueness in-memory (throw, replace, or update existing) to mirror persisted templates.
|
|
||
| ```php | ||
| $template->section('demographics')->disable(); | ||
| $template->reorderSections(['body', 'demographics']); |
There was a problem hiding this comment.
This documentation example reorders sections using a 'body' slug that isn’t created in the snippet. That makes the example misleading (and, with the current implementation, will just skip the unknown slug and set 'demographics' to order 1). Update the example to only include existing section slugs, or add creation of the missing section before reordering.
| $template->reorderSections(['body', 'demographics']); | |
| $template->reorderSections(['demographics']); |
| // --------------------------------------------------------------- | ||
|
|
||
| it('executes no database queries', function () { | ||
| \Illuminate\Support\Facades\DB::enableQueryLog(); |
There was a problem hiding this comment.
The DB query log assertion can be flaky if any query happens after enableQueryLog() for reasons unrelated to the code under test (e.g., deferred service resolution). Consider flushing the query log immediately after enabling it (or using DB::connection()->pretend()) so the assertion only reflects queries executed by the ephemeral operations in this test.
| \Illuminate\Support\Facades\DB::enableQueryLog(); | |
| \Illuminate\Support\Facades\DB::enableQueryLog(); | |
| \Illuminate\Support\Facades\DB::flushQueryLog(); |
Summary
This PR introduces ephemeral templates to Schematic — in-memory, non-persisted templates that can be created and used at runtime without any database overhead. Ephemeral templates support the same core features as database-backed templates: sections, fields, JSON Schema generation, rendering, and previewing.
Key Changes
New
EphemeralTemplateclass — A fluent, in-memory template implementation that mirrors the database-backedTemplatemodel APImake()factory method for creationaddSection(),section(),iterateSections(),iterateAllSections(),reorderSections()toJsonSchema(),toJsonSchemaDocument(),sectionSchema()render()andpreview()methodsNew
EphemeralSectionclass — In-memory section implementation with fluent buildersmake()factory methodaddField(),removeField(),fieldDefinitions()enable(),disable()setExamples()method for preview dataService integration — Added
ephemeral()method toSchematicservice for convenient creation via the facadeComprehensive test coverage — 26 feature tests covering:
Documentation — Updated README with ephemeral template usage examples and API reference
Implementation Details
EphemeralTemplateandEphemeralSectionimplementRenderableandSchemaGeneratablecontracts, ensuring API consistency with database-backed templatesschematic.schema.strictconfiguration foradditionalPropertiesCompilerservice for template processing