Skip to content

ADR-171: Implement LayoutCompilerService as Native AOT Lambda#198

Open
jodavis-claude wants to merge 14 commits into
feature/ADR-161-cusrtomization-servicefrom
dev/jodavis/dev-team-scripted
Open

ADR-171: Implement LayoutCompilerService as Native AOT Lambda#198
jodavis-claude wants to merge 14 commits into
feature/ADR-161-cusrtomization-servicefrom
dev/jodavis/dev-team-scripted

Conversation

@jodavis-claude
Copy link
Copy Markdown
Collaborator

Summary

  • Implements AdaptiveRemote.Backend.LayoutCompilerService as a .NET 10 Native AOT Lambda function
  • Adds POST /compile (RawLayout → CompiledLayout) and POST /compile/preview (elements → PreviewLayout) endpoints
  • Replaces the StubLayoutCompilerClient in LayoutProcessingService with HttpLayoutCompilerClient backed by the real Lambda
  • Fixes git worktree detection in ServiceFixture (Path.Exists instead of Directory.Exists)

What changed

New: AdaptiveRemote.Backend.LayoutCompilerService

  • Native AOT Lambda (AssemblyName=bootstrap, PublishAot=true) serving HTTP via AddAWSLambdaHosting
  • LayoutCompiler service: pure synchronous compilation — strips grid/CSS authoring properties, generates CssDefinitions from RawLayoutElementDto grid positions and AdditionalCss, produces preview HTML/CSS
  • All serialization through LayoutContractsJsonContext; no reflection-based JSON
  • Log messages 1800–1803 in MessageLogger.cs (shared AdaptiveRemote.Backend.Common)
  • Scalar UI guarded by IsDevelopment(); health endpoint at GET /health
  • localstack-init/02-deploy-lambda.sh provisions the function in LocalStack on startup

Updated: AdaptiveRemote.Backend.LayoutProcessingService

  • HttpLayoutCompilerClient replaces StubLayoutCompilerClient — calls the real Lambda over HTTP
  • StubLayoutValidationClient updated: detects the invalid path via .INVALID_ prefix in CssDefinitions (emitted by the real compiler) rather than the hardcoded "INVALID" string from the old stub
  • E2E test updated to use cssId: "INVALID_up-btn" to trigger the validation failure path

Design notes

  • LayoutCompilerService is stateless and has no external dependencies (no LocalStack, no DynamoDB, no SQS), so it does not include a LocalStack startup health check — consistent with the Lambda pattern in _doc_BackendDevelopment.md
  • The INVALID_ prefix convention for exercising the validation failure path in E2E tests is documented in StubLayoutValidationClient

Work item

ADR-171: https://jodasoft.atlassian.net/browse/ADR-171

Directory.Exists() returns false when .git is a file (git worktree layout).
Path.Exists() accepts both files and directories, so it correctly finds the
repo root in worktree checkouts.
StubLayoutValidationClient was checking CssDefinitions == "INVALID", which was
set by the now-replaced StubLayoutCompilerClient. With HttpLayoutCompilerClient,
the signal is embedded in the element cssId: any cssId starting with "INVALID_"
causes the real LayoutCompilerService to emit ".INVALID_<id>" in CssDefinitions,
which the stub then detects. Update the E2E test to use cssId "INVALID_up-btn"
to exercise the failure path end-to-end.
@jodavis-claude
Copy link
Copy Markdown
Collaborator Author

Code review findings posted for ADR-171.

@jodavis-claude
Copy link
Copy Markdown
Collaborator Author

Code Review ADR-171

Two blocking issues and one nit found.

BLOCKING 1 — Missing Properties/launchSettings.json for LayoutCompilerService
File: src/AdaptiveRemote.Backend.LayoutCompilerService/AdaptiveRemote.Backend.LayoutCompilerService.csproj

_doc_BackendDevelopment.md requires: all Lambda projects must include a launch profile for the Lambda Test Tool. The ADR-171 exit criterion is Lambda Test Tool launch profile present. Every ECS Fargate service has a Properties/launchSettings.json; this Lambda service has none. Add a Properties/launchSettings.json with a Lambda Test Tool launch profile.

BLOCKING 2 — _doc_BackendDevelopment.md is stale after ADR-171
File: src/_doc_BackendDevelopment.md line 28 and line 33

Line 28 still says: Compile via ILayoutCompilerClient (stub: StubLayoutCompilerClient). ADR-171 replaced that stub with HttpLayoutCompilerClient backed by the real Lambda. Update step 3 to reference the real client. Also remove the StubLayoutCompilerClient bullet from the Stub implementations section since that stub no longer exists.

NIT — StubLayoutValidationClient._forceInvalid is dead code
File: src/AdaptiveRemote.Backend.LayoutProcessingService/Services/StubLayoutValidationClient.cs line 16

forceInvalid is assigned from IConfiguration in the constructor but never read. It became unused when the stub was updated to detect the .INVALID prefix in CssDefinitions rather than a config flag. Remove the field and the IConfiguration constructor injection.

_doc_BackendDevelopment.md requires all Lambda projects to have a launch
profile for the Lambda Test Tool. This file was missing from the initial
ADR-171 implementation.
…erClient references

Pipeline step 3 now reflects HttpLayoutCompilerClient (the real HTTP client
added by ADR-171). Remove StubLayoutCompilerClient from the Stub
implementations list; it is no longer used.
…LayoutValidationClient

_forceInvalid was assigned from IConfiguration but never read after the
stub was updated to detect .INVALID_ in CssDefinitions. Remove the field
and the IConfiguration constructor injection.
@jodavis jodavis changed the base branch from main to feature/ADR-161-cusrtomization-service May 21, 2026 16:51
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 21, 2026

Test Results

459 tests   450 ✅  3m 25s ⏱️
  9 suites    0 💤
  9 files      9 ❌

For more details on these failures, see this check.

Results for commit c452ce5.

♻️ This comment has been updated with latest results.

@jodavis-claude
Copy link
Copy Markdown
Collaborator Author

Sign-off Review — ADR-171

Prior issues — all resolved:

  • BLOCKING 1 (launchSettings.json): Added with a valid Lambda Test Tool launch profile. Resolved.
  • BLOCKING 2 (_doc_BackendDevelopment.md stale): Step 3 updated to HttpLayoutCompilerClient; StubLayoutCompilerClient entry removed. Resolved.
  • NIT (StubLayoutValidationClient dead code): _forceInvalid field and IConfiguration injection removed. Resolved.

New issue in post-review modified file (Priority 5 — Documentation):
src/_doc_BackendDevelopment.md line 32:

StubLayoutValidationClient — always returns IsValid=true; set Validation:ForceInvalid=true to exercise the failure path

The Validation:ForceInvalid=true config key was removed along with forceInvalid when StubLayoutValidationClient was updated. The failure path is now triggered by giving a layout element a cssId starting with INVALID (the real LayoutCompilerService emits .INVALID_ verbatim in CssDefinitions, which the stub detects).

Suggested replacement:

StubLayoutValidationClient — always returns IsValid=true; E2E tests trigger the failure path by giving a layout element a cssId starting with INVALID_ (the compiler emits .INVALID_ in CssDefinitions, which the stub detects)

Note: GitHub prevents submitting a formal review on your own PR. This comment records the sign-off findings in lieu of a formal review submission.

…evelopment.md

The config key was removed when StubLayoutValidationClient was updated to detect
.INVALID_ in CssDefinitions. Update the stub description to document the current
failure-path mechanism: give a layout element a cssId starting with INVALID_.
@jodavis-claude
Copy link
Copy Markdown
Collaborator Author

Sign-off Review #2 — ADR-171

Prior sign-off issue — resolved:

No new issues found in src/_doc_BackendDevelopment.md (the only file modified since the prior sign-off).

All exit criteria met. No Priority 1–5 issues remain. APPROVED.

Note: GitHub prevents submitting a formal review on your own PR. This comment records the sign-off in lieu of a formal review submission.

@jodavis-claude jodavis-claude requested a review from jodavis May 21, 2026 17:19
@jodavis
Copy link
Copy Markdown
Owner

jodavis commented May 21, 2026

@copilot There are ApiTests failing during the build-and-test job, but ApiTests are supposed to be filtered out during that job. Can you investigate why they attempted to run during the latest PR run?

Copy link
Copy Markdown
Contributor

Copilot AI commented May 21, 2026

@copilot There are ApiTests failing during the build-and-test job, but ApiTests are supposed to be filtered out during that job. Can you investigate why they attempted to run during the latest PR run?

Investigated on run 26241501345 (commit c452ce5). In build-and-test, Unit Tests run dotnet test ./scripts/validate-unit-tests.proj --filter "TestCategory!=ApiIntegrationTest", but validate-unit-tests.proj still includes test/**/*.csproj, including AdaptiveRemote.Backend.ApiTests.csproj. Several ApiTests features (AuthenticationEndpoints.feature, CompiledLayoutEndpoints.feature, HealthEndpoints.feature) are missing @ApiIntegrationTest, so their generated tests have no TestCategory("ApiIntegrationTest") and are not filtered out. That’s why ApiTests attempted to run in the Unit Tests job.

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.

4 participants