Skip to content

Add ephemeral (in-memory) template support#3

Merged
yannelli merged 1 commit intomainfrom
claude/ephemeral-templates-SmZru
Mar 19, 2026
Merged

Add ephemeral (in-memory) template support#3
yannelli merged 1 commit intomainfrom
claude/ephemeral-templates-SmZru

Conversation

@yannelli
Copy link
Copy Markdown
Owner

@yannelli yannelli commented Mar 19, 2026

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 EphemeralTemplate class — A fluent, in-memory template implementation that mirrors the database-backed Template model API

    • Constructor and make() factory method for creation
    • Section management: addSection(), section(), iterateSections(), iterateAllSections(), reorderSections()
    • JSON Schema generation: toJsonSchema(), toJsonSchemaDocument(), sectionSchema()
    • Content rendering: render() and preview() methods
    • Full support for metadata and descriptions
  • New EphemeralSection class — In-memory section implementation with fluent builders

    • Constructor and make() factory method
    • Field management: addField(), removeField(), fieldDefinitions()
    • Enable/disable control: enable(), disable()
    • JSON Schema generation from field definitions
    • Content rendering with example data support
    • Fluent setExamples() method for preview data
  • Service integration — Added ephemeral() method to Schematic service for convenient creation via the facade

  • Comprehensive test coverage — 26 feature tests covering:

    • Template and section creation
    • Section management and reordering
    • JSON Schema generation for templates and sections
    • Content rendering with data and conditionals
    • Preview functionality with example data
    • Fluent builder methods
    • Zero database query verification
  • Documentation — Updated README with ephemeral template usage examples and API reference

Implementation Details

  • Both EphemeralTemplate and EphemeralSection implement Renderable and SchemaGeneratable contracts, ensuring API consistency with database-backed templates
  • Sections are stored in-memory as an array and sorted by order on iteration
  • Schema generation respects the schematic.schema.strict configuration for additionalProperties
  • Rendering uses the existing Compiler service for template processing
  • All operations are zero-database-query by design — no persistence layer involved

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
Copilot AI review requested due to automatic review settings March 19, 2026 20:42
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 EphemeralTemplate and EphemeralSection classes that mirror the persisted Template/Section API 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;
Copy link

Copilot AI Mar 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.

```php
$template->section('demographics')->disable();
$template->reorderSections(['body', 'demographics']);
Copy link

Copilot AI Mar 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
$template->reorderSections(['body', 'demographics']);
$template->reorderSections(['demographics']);

Copilot uses AI. Check for mistakes.
// ---------------------------------------------------------------

it('executes no database queries', function () {
\Illuminate\Support\Facades\DB::enableQueryLog();
Copy link

Copilot AI Mar 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
\Illuminate\Support\Facades\DB::enableQueryLog();
\Illuminate\Support\Facades\DB::enableQueryLog();
\Illuminate\Support\Facades\DB::flushQueryLog();

Copilot uses AI. Check for mistakes.
@yannelli yannelli merged commit b72951c into main Mar 19, 2026
8 checks passed
@yannelli yannelli deleted the claude/ephemeral-templates-SmZru branch March 19, 2026 20:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants