@juangcarmona/lighthouse 0.5.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -2
- package/assets/dotnet-template/Directory.Build.props +22 -0
- package/assets/dotnet-template/Directory.Packages.props +16 -0
- package/assets/dotnet-template/Lighthouse.Analyzers/BackendContractAnalyzer.cs +72 -0
- package/assets/dotnet-template/Lighthouse.Analyzers/Lighthouse.Analyzers.csproj +12 -0
- package/assets/dotnet-template/Lighthouse.Analyzers/packages.lock.json +121 -0
- package/assets/dotnet-template/Lighthouse.Cqrs/Handlers.cs +11 -0
- package/assets/dotnet-template/Lighthouse.Cqrs/Lighthouse.Cqrs.csproj +5 -0
- package/assets/dotnet-template/Lighthouse.Cqrs/packages.lock.json +6 -0
- package/assets/dotnet-template/Lighthouse.slnx +17 -0
- package/assets/dotnet-template/examples/src/modules/Lighthouse.Example.Modules.Catalog/CatalogModule.cs +24 -0
- package/assets/dotnet-template/examples/src/modules/Lighthouse.Example.Modules.Catalog/Features/Entries/CreateEntry.cs +47 -0
- package/assets/dotnet-template/examples/src/modules/Lighthouse.Example.Modules.Catalog/Features/Entries/EntryStore.cs +17 -0
- package/assets/dotnet-template/examples/src/modules/Lighthouse.Example.Modules.Catalog/Features/Entries/GetEntry.cs +30 -0
- package/assets/dotnet-template/examples/src/modules/Lighthouse.Example.Modules.Catalog/Lighthouse.Example.Modules.Catalog.csproj +12 -0
- package/assets/dotnet-template/examples/src/modules/Lighthouse.Example.Modules.Catalog/packages.lock.json +10 -0
- package/assets/dotnet-template/examples/src/root/Lighthouse.Example.Api/Lighthouse.Example.Api.csproj +6 -0
- package/assets/dotnet-template/examples/src/root/Lighthouse.Example.Api/Program.cs +25 -0
- package/assets/dotnet-template/examples/src/root/Lighthouse.Example.Api/Properties/launchSettings.json +10 -0
- package/assets/dotnet-template/examples/src/root/Lighthouse.Example.Api/packages.lock.json +86 -0
- package/assets/dotnet-template/examples/src/root/Lighthouse.Example.AppHost/Lighthouse.Example.AppHost.csproj +13 -0
- package/assets/dotnet-template/examples/src/root/Lighthouse.Example.AppHost/Program.cs +3 -0
- package/assets/dotnet-template/examples/src/root/Lighthouse.Example.AppHost/Properties/launchSettings.json +15 -0
- package/assets/dotnet-template/examples/src/root/Lighthouse.Example.AppHost/aspire.config.json +5 -0
- package/assets/dotnet-template/examples/src/root/Lighthouse.Example.AppHost/packages.lock.json +689 -0
- package/assets/dotnet-template/global.json +6 -0
- package/assets/dotnet-template/tests/Lighthouse.Analyzers.Tests/BackendContractTests.cs +102 -0
- package/assets/dotnet-template/tests/Lighthouse.Analyzers.Tests/Lighthouse.Analyzers.Tests.csproj +9 -0
- package/assets/dotnet-template/tests/Lighthouse.Analyzers.Tests/packages.lock.json +125 -0
- package/assets/dotnet-template/tests/Lighthouse.Example.Tests/CatalogTests.cs +111 -0
- package/assets/dotnet-template/tests/Lighthouse.Example.Tests/Lighthouse.Example.Tests.csproj +9 -0
- package/assets/dotnet-template/tests/Lighthouse.Example.Tests/packages.lock.json +490 -0
- package/assets/profiles/catalog.json +1050 -0
- package/assets/profiles/dotnet/README.md +32 -0
- package/assets/profiles/dotnet/SKILL.md +18 -0
- package/assets/profiles/dotnet/adoption.md +39 -0
- package/assets/profiles/dotnet/architecture.md +37 -0
- package/assets/profiles/dotnet/guardrails.md +32 -0
- package/assets/profiles/dotnet/practices.md +36 -0
- package/assets/profiles/dotnet/testing-and-development.md +29 -0
- package/assets/profiles/dotnet/use-cases.md +29 -0
- package/assets/profiles/mobile-expo/README.md +19 -0
- package/assets/profiles/mobile-expo/SKILL.md +14 -0
- package/assets/profiles/mobile-expo/adoption.md +11 -0
- package/assets/profiles/mobile-expo/guardrails.md +14 -0
- package/assets/profiles/mobile-expo/testing.md +13 -0
- package/assets/profiles/mobile-maui/README.md +19 -0
- package/assets/profiles/mobile-maui/SKILL.md +14 -0
- package/assets/profiles/mobile-maui/adoption.md +11 -0
- package/assets/profiles/mobile-maui/guardrails.md +13 -0
- package/assets/profiles/mobile-maui/testing.md +13 -0
- package/assets/profiles/pwa-capability/README.md +19 -0
- package/assets/profiles/pwa-capability/SKILL.md +14 -0
- package/assets/profiles/pwa-capability/adoption.md +9 -0
- package/assets/profiles/pwa-capability/guardrails.md +13 -0
- package/assets/profiles/pwa-capability/offline.md +11 -0
- package/assets/profiles/pwa-capability/testing.md +15 -0
- package/assets/profiles/react-web-platform/README.md +24 -0
- package/assets/profiles/react-web-platform/SKILL.md +18 -0
- package/assets/profiles/react-web-platform/adoption.md +17 -0
- package/assets/profiles/react-web-platform/guardrails.md +17 -0
- package/assets/profiles/react-web-platform/structure.md +36 -0
- package/assets/profiles/react-web-platform/testing.md +15 -0
- package/assets/profiles/web-bff/README.md +22 -0
- package/assets/profiles/web-bff/SKILL.md +16 -0
- package/assets/profiles/web-bff/adoption.md +9 -0
- package/assets/profiles/web-bff/security.md +16 -0
- package/assets/profiles/web-bff/testing.md +14 -0
- package/assets/schemas/lighthouse-manifest.schema.json +10 -7
- package/assets/schemas/profile-catalog.schema.json +329 -0
- package/package.json +5 -2
- package/src/create-dotnet.mjs +112 -0
- package/src/lighthouse.mjs +109 -14
- package/src/profiles.mjs +206 -0
- package/src/verify-dotnet.mjs +85 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Lighthouse .NET profile
|
|
2
|
+
|
|
3
|
+
Use this profile to create an ASP.NET Core backend or assess an existing one. The executable reference targets .NET 10 and combines Minimal APIs, one file per command/query slice, a modular monolith structure, Aspire development orchestration, typed CQRS contracts and Roslyn boundary checks.
|
|
4
|
+
|
|
5
|
+
| Start here | Then follow |
|
|
6
|
+
| --- | --- |
|
|
7
|
+
| New backend | [Adoption](adoption.md#new-backend) → [layout and boundaries](architecture.md) → [one-file use cases](use-cases.md) |
|
|
8
|
+
| Existing backend | [Assessment and adoption](adoption.md#existing-backend) → [guardrail matrix](guardrails.md) |
|
|
9
|
+
| Implement a capability | [Use-case contract](use-cases.md) → [tests](testing-and-development.md) |
|
|
10
|
+
| Review all backend practices | [Practice catalog, applicability and real mechanisms](practices.md) |
|
|
11
|
+
| Diagnose a failed build | [Diagnostics and exceptions](guardrails.md) |
|
|
12
|
+
|
|
13
|
+
## Defaults
|
|
14
|
+
|
|
15
|
+
- Start with one deployable API. Introduce a module only for a real ownership, domain, data or lifecycle boundary; keep features within a module by default.
|
|
16
|
+
- Use Minimal APIs. Place transport mapping, request/response records, command or query, validator and handler in one use-case file. Keep the handler independent of HTTP.
|
|
17
|
+
- Keep handlers `internal sealed`. Expose module composition and intentionally designed contracts; do not expose persistence or domain implementation types.
|
|
18
|
+
- Treat commands and queries as separate responsibilities. CQRS does not require separate databases, a broker or eventual consistency.
|
|
19
|
+
- Validate before side effects. Translate expected outcomes into useful HTTP statuses/ProblemDetails at the endpoint. Propagate cancellation.
|
|
20
|
+
- Run analyzers during local build and CI, back them with semantic tests and retain a narrow exception process.
|
|
21
|
+
|
|
22
|
+
## Working implementation
|
|
23
|
+
|
|
24
|
+
```sh
|
|
25
|
+
dotnet restore src/dotnet/Lighthouse.slnx --locked-mode
|
|
26
|
+
npm run verify:dotnet
|
|
27
|
+
dotnet run --project src/dotnet/examples/src/root/Lighthouse.Example.Api
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
The distributed starter includes a Catalog example that exercises a POST command and GET query. Its store is in memory and deliberately disposable. JWT authorization is enforced; test identities live only in the test assembly. Production persistence, multitenancy, migrations, distributed caching and outbox delivery require product-specific design and tests.
|
|
31
|
+
|
|
32
|
+
The [enforcement table](guardrails.md) distinguishes implemented rules from recommendations. No rule implies remote branch protection or production readiness.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: lighthouse-dotnet
|
|
3
|
+
description: Apply the Lighthouse .NET profile when a repository selects the dotnet-backend profile.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Lighthouse .NET profile
|
|
7
|
+
|
|
8
|
+
Read the profile guide before changing a .NET adopter.
|
|
9
|
+
|
|
10
|
+
Keep the default backend as a feature-aligned modular monolith with Minimal API endpoints, one file per command or query, internal sealed handlers and explicit module contracts.
|
|
11
|
+
|
|
12
|
+
Use Aspire as the composition boundary and keep analyzers active in every implementation module.
|
|
13
|
+
|
|
14
|
+
Use red-green development: start with unit tests, then add integration, functional and browser evidence when the selected application surface needs them.
|
|
15
|
+
|
|
16
|
+
Run `npm run verify` and `npm run verify:dotnet` after a focused change. Treat unavailable evidence as a repair action, not as proof of compliance.
|
|
17
|
+
|
|
18
|
+
Application code, tests and build policy become adopter-owned after creation. Do not overwrite them from the profile.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Adopt the Lighthouse .NET profile
|
|
2
|
+
|
|
3
|
+
## New backend
|
|
4
|
+
|
|
5
|
+
From a Lighthouse checkout:
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
npm run create:dotnet -- /tmp/Workshop --name Workshop
|
|
9
|
+
cd /tmp/Workshop
|
|
10
|
+
dotnet restore Workshop.slnx
|
|
11
|
+
npm run verify
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
The creator accepts a new directory or an existing empty directory. It validates the C# product name and refuses a populated target. It seeds a self-contained original backend, analyzer/CQRS source, tests, manifest, SDK/package policy and CI definition. No remote repository or external service is created.
|
|
15
|
+
|
|
16
|
+
Keep one command and one query before adding a second module or persistence. Change example domain behavior through product requirements, add the real identity configuration, then select persistence, tenancy and deployment only when needed. Follow [the layout](architecture.md) and [single-file contract](use-cases.md).
|
|
17
|
+
|
|
18
|
+
## Existing backend
|
|
19
|
+
|
|
20
|
+
1. Inventory framework/SDK, layout, domain seams, data ownership, authentication, analysis, tests, CI and local startup. Preserve existing work.
|
|
21
|
+
2. Map current code to profile defaults. Document valuable differences before changing paths or public APIs.
|
|
22
|
+
3. Add pinned analyzer/CQRS source from an accepted Lighthouse revision in an isolated change. Keep a repository snapshot/version record. Adapt a rule if the product uses different handler contracts or assembly naming; prove the adapter with compiler fixtures.
|
|
23
|
+
4. Enable one module at a time. Establish positive tests and inspect every new diagnostic; use narrow expiring exceptions during migration.
|
|
24
|
+
5. Choose one low-risk command/query and adopt the file contract without moving unrelated features. Add functional authorization/validation tests.
|
|
25
|
+
6. Run local checks, then wire them into CI. Make checks required through the product's hosting policy only after runtime and flakiness are understood.
|
|
26
|
+
|
|
27
|
+
The creator is for new products; never run it over an existing checkout.
|
|
28
|
+
|
|
29
|
+
## File ownership and upgrades
|
|
30
|
+
|
|
31
|
+
| Content | Owner after creation | Upgrade path |
|
|
32
|
+
| --- | --- | --- |
|
|
33
|
+
| Application, tests, build policy, analyzer/CQRS source and workflow | Product | Seeded snapshot, then editable; manually review Lighthouse changes, adapt and rerun verification |
|
|
34
|
+
| `lighthouse.json` | Product | Select baseline/profile/integration pins explicitly |
|
|
35
|
+
| `LIGHTHOUSE.md` | Lighthouse projection | Generate/check through the pinned local verifier |
|
|
36
|
+
| Lockfiles | Package manager, committed by product | Intentional restore/update, inspect resolved diff |
|
|
37
|
+
| `bin`, `obj`, reports | Disposable build output | Regenerate; never hand-edit |
|
|
38
|
+
|
|
39
|
+
The current creator is a source starter, not a synchronized framework installer. Drift detection covers the declared managed projection; application/tooling changes are product-owned and are not silently overwritten. There is no automatic bulk upgrade. For repeatable adoption, retain the accepted Lighthouse commit or distributed source bundle in the product's tooling record.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Backend structure and boundaries
|
|
2
|
+
|
|
3
|
+
Use the product namespace under juangcarmona. The example's namespace is `JuanGCarmona.Lighthouse.Example`; the creator replaces it with `JuanGCarmona.<Product>`. Established products retain their namespace as a documented adoption choice.
|
|
4
|
+
|
|
5
|
+
```text
|
|
6
|
+
src/
|
|
7
|
+
root/<Product>.Api/ host, HTTP policy, composition
|
|
8
|
+
root/<Product>.AppHost/ optional development orchestration
|
|
9
|
+
modules/<Product>.Modules.<Name>/
|
|
10
|
+
<Name>Module.cs public registration and route composition
|
|
11
|
+
Features/<Feature>/
|
|
12
|
+
CreateThing.cs one complete command slice
|
|
13
|
+
GetThing.cs one complete query slice
|
|
14
|
+
Domain/ when the feature needs domain behavior
|
|
15
|
+
Infrastructure/Persistence/ when there is actual persistence
|
|
16
|
+
dotnet/Lighthouse.Cqrs/ initial typed command/query contracts
|
|
17
|
+
dotnet/Lighthouse.Analyzers/ local, versioned tooling source
|
|
18
|
+
src/dotnet/tests/ analyzer, HTTP and architecture tests
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Paths describe responsibilities; create folders only when they hold real code. The distributed starter keeps its examples under `src/`; generated products start directly under `src/`.
|
|
22
|
+
|
|
23
|
+
## Dependencies
|
|
24
|
+
|
|
25
|
+
The API host composes modules. A module may depend on a sibling's separate `.Contracts` assembly, never its implementation assembly. Add a contracts project only when a consumer exists. Keep contracts small: integration DTOs, stable interfaces and events that describe a real boundary. A separate contracts assembly is a structural boundary; it does not by itself guarantee safe data exposure or correct authorization.
|
|
26
|
+
|
|
27
|
+
Within a feature, use cases coordinate domain behavior and infrastructure. A command may write; a query returns a read model and must not mutate business state. Keep the domain independent of ASP.NET Core and storage APIs. A schema/DbContext per module is recommended when data ownership warrants that cost; cross-module joins or shared tables need an explicit decision. An in-memory single-module example cannot prove those persistence boundaries.
|
|
28
|
+
|
|
29
|
+
## Composition and cross-cutting behavior
|
|
30
|
+
|
|
31
|
+
Use explicit DI registration first. Introduce scanning or dispatch only when it removes measured repetition. The example injects typed handlers directly; it makes no mediator package mandatory. When logging, validation, authorization or caching become decorators, document and test their order. Authorization belongs at the edge and at the relevant domain/data boundary; validation must execute before mutation, including invocations outside HTTP.
|
|
32
|
+
|
|
33
|
+
Transactions belong to the consistency boundary of a command. Use domain events for real domain coordination; introduce an outbox when delivery must survive process/transaction failure. Cache keys and invalidation must be tested together. These capabilities are recommendations with adoption costs, not speculative packages in the starter.
|
|
34
|
+
|
|
35
|
+
## Runtime and diagnostics
|
|
36
|
+
|
|
37
|
+
Aspire owns the optional local dependency graph and startup feedback. A deployment can use containers, a managed host or another product-approved topology. Production readiness covers configuration, identity, persistent data, migrations, health, telemetry, backup/recovery and release controls; the example implements only the smaller contract documented in its README.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# .NET guardrails and enforcement
|
|
2
|
+
|
|
3
|
+
Each product maintainer owns activation and exceptions. Lighthouse maintainers own the reference diagnostics and their tests. The distinction between implemented and recommended checks is part of the contract.
|
|
4
|
+
|
|
5
|
+
| Rule | Mechanism now | Failure | Exception / owner |
|
|
6
|
+
| --- | --- | --- | --- |
|
|
7
|
+
| LH1001: handlers stay internal sealed | Roslyn semantic rule for implementations of `JuanGCarmona.Lighthouse.Cqrs.ICommandHandler<,>` / `IQueryHandler<,>` | Error during module build | Maintainer records a narrow suppression and rationale; test the changed boundary |
|
|
8
|
+
| LH1002: sibling module access uses Contracts | Roslyn compilation rule checks assembly references in the same `.Modules.` family | Error even for an unused implementation reference | Redesign dependency; temporary scoped suppression requires owner/review date |
|
|
9
|
+
| Every implementation module activates the rules | Verifier inspects evaluated MSBuild properties and analyzer references for solution projects | Verifier fails if a named module silently omits enforcement | Product maintainer defines an explicit migration scope before adopting this full verifier |
|
|
10
|
+
| Nullable correctness and SDK analysis | `src/dotnet/Directory.Build.props`, warnings-as-errors | Compiler/analysis warning fails build | Narrow documented suppression |
|
|
11
|
+
| Formatting | `.editorconfig` and `dotnet format whitespace --verify-no-changes` | Verifier fails on whitespace drift | Product-owned formatting policy |
|
|
12
|
+
| Reproducible dependency resolution | Pinned versions, SDK feature band, committed NuGet locks, locked restore | Restore fails on drift | Reviewed dependency update regenerates locks |
|
|
13
|
+
| Known dependency vulnerabilities | NuGet audit of all dependencies; warnings-as-errors | Restore fails for reported advisories at low or above | Security owner decides explicit, expiring risk acceptance; no blanket audit disable |
|
|
14
|
+
| HTTP validation and authorization | Functional tests of 400/401/403/201/200/404 behavior | Test fails | Accepted behavior changes require corresponding product decision |
|
|
15
|
+
| Compiled module boundary | Reflection architecture test checks exported handlers and references | Test fails | Match product's actual architectural contract |
|
|
16
|
+
| Broken compilation rules really fail build | `src/packages/cli/internal/verify-dotnet.mjs` compiles deliberately invalid temporary projects | Verifier fails unless LH1001 and LH1002 reject the fixture | Fix tooling; never accept a fixture merely because a unit test passed |
|
|
17
|
+
| Public entity leaks, controller prohibition, domain-framework dependency | Documented profile rules; targeted automated rules are future work | Review finding today | Maintainer records exception; do not claim automatic enforcement |
|
|
18
|
+
| Persistent data/tenant isolation | Product-specific integration tests, recommended | No coverage in this in-memory example | Product owner and security/data owner define requirements |
|
|
19
|
+
|
|
20
|
+
## Activation
|
|
21
|
+
|
|
22
|
+
Attach the analyzer as an analyzer-only project reference, set `LighthouseModule=true` on implementation projects, and expose that property with `CompilerVisibleProperty`. Module assembly names follow `<Root>.Modules.<Name>` and separate contract assemblies end in `.Contracts`. The distributed Catalog project and build properties are the executable contract.
|
|
23
|
+
|
|
24
|
+
`LH1001` recognizes the supplied CQRS interfaces semantically, including aliases/inheritance. A different mediator/handler abstraction needs an adapter or another tested rule; class-name conventions alone are not enforcement. The rule skips compiler-generated code. `LH1002` checks compilation references for the configured naming family; it does not inspect payload semantics, reflection-based access, network calls or dependency injection at runtime. Use architecture/functional tests for those boundaries.
|
|
25
|
+
|
|
26
|
+
## Diagnostic lifecycle
|
|
27
|
+
|
|
28
|
+
New rules require positive and negative compiler fixtures, a stable diagnostic ID, useful remediation, release tracking and a failing-build rehearsal. Keep their compiler API compatible with the supported SDK. Move rules to the shipped ledger only as part of an accepted release. The current analyzers are local source tooling, not a published NuGet package.
|
|
29
|
+
|
|
30
|
+
## Exceptions
|
|
31
|
+
|
|
32
|
+
Record rule/diagnostic, affected paths, reason, owner, review date and compensating test. Suppress the smallest symbol/project scope, and remove the suppression after the migration. An architectural exception must not be disguised as generated code. CI runs the same verifier; required merge status still depends on the host's branch rules.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Backend practice catalog
|
|
2
|
+
|
|
3
|
+
This catalog makes the profile reviewable. Product code owners choose applicability; security/data owners accept changes to their boundaries. “Reference” means the example demonstrates a pattern. “Enforced” names the current tool. A recommendation becomes a gate only after a product implements and verifies it.
|
|
4
|
+
|
|
5
|
+
| Practice | Problem addressed / when to apply | Mechanism in this release |
|
|
6
|
+
| --- | --- | --- |
|
|
7
|
+
| One deployable host, modules at real seams | Keep operations simple while preserving domain/data ownership; extra modules add coordination cost | Reference layout; boundary design is a review decision |
|
|
8
|
+
| Feature-first organization | Keep behavior changes adjacent; avoid mandatory layer-by-layer file hopping | Reference and guidance |
|
|
9
|
+
| One file per command/query | Keep route, DTOs, request, validation and handler together | Reference and review; file shape has no custom analyzer yet |
|
|
10
|
+
| CQRS without separate storage by default | Distinguish reads from writes without adding a broker/read replica prematurely | Typed handler contracts and two working slices |
|
|
11
|
+
| HTTP-independent handlers | Reuse/test application behavior without transport dependencies | Reference; dedicated dependency rule is future work |
|
|
12
|
+
| Internal sealed handlers | Prevent application implementation from becoming a public API or inheritance surface | Enforced LH1001 for supported handler interfaces |
|
|
13
|
+
| Public composition, private implementation | Make module registration explicit; expose only deliberate integration contracts | Reference; public entity-leak rule is future work |
|
|
14
|
+
| Sibling Contracts assemblies | Stop modules depending on implementation internals; add contracts only for an actual consumer | Enforced LH1002 plus compiled architecture test |
|
|
15
|
+
| Small shared kernel | Keep genuinely common technical contracts in one place without building an internal framework | Two typed handler interfaces; review additional abstractions |
|
|
16
|
+
| Validation before side effects | Reject bad commands whether invoked through HTTP or another path | Reference handler validates before mutation; HTTP tests |
|
|
17
|
+
| Explicit typed outcomes / ProblemDetails | Keep expected failures separate from unexpected exceptions and stable at the edge | Reference validation/missing-resource responses; HTTP tests |
|
|
18
|
+
| Cross-cutting pipeline with tested order | Avoid inconsistent logging/validation/cache behavior after repetition justifies decorators | Recommendation; document order and test cache invalidation if introduced |
|
|
19
|
+
| Trusted identity and authorization | Prevent callers from selecting their own owner/tenant boundary | JWT edge policy and 401/403 tests; tenant data checks require a persistent product slice |
|
|
20
|
+
| Module-owned persistence and migrations | Avoid accidental shared-table coupling; separate schema/DbContext when ownership warrants the complexity | Recommendation; example has only in-memory storage |
|
|
21
|
+
| Transaction boundaries per command | Make all-or-nothing behavior and concurrency conflicts explicit | Recommendation; database-backed tests required when introduced |
|
|
22
|
+
| Domain events with durable delivery when needed | Keep domain coordination explicit; use an outbox only when delivery must survive failure | Recommendation; no event/outbox framework in the starter |
|
|
23
|
+
| Read-model cache and tested invalidation | Reduce measured read cost without returning stale business state | Recommendation; no cache in the reference |
|
|
24
|
+
| Cancellation and explicit identifiers | Bound abandoned work and expose stable resource identity | Reference propagates CancellationToken and uses GUID-v7 identifiers |
|
|
25
|
+
| Same-origin/BFF where appropriate | Simplify browser session and API trust boundaries for products that benefit from one web origin | Optional architecture choice; no frontend/BFF in the example |
|
|
26
|
+
| Generated API contracts | Detect API/client drift while keeping generated files disposable | Recommendation; require a real consumer before adding generation |
|
|
27
|
+
| Structured logs and trace context | Diagnose a failed use case without logging sensitive payloads | Host development logging; exporter, redaction and event-ID policies remain product work |
|
|
28
|
+
| Aspire development graph | Start related services with observable readiness and coherent configuration | Runnable AppHost for the API; provision only dependencies the product uses |
|
|
29
|
+
| Layered verification by risk | Catch cheap faults early and reserve expensive journeys for valuable system behavior | Semantic analyzer, architecture and HTTP tests; engine/browser backend journeys added when needed |
|
|
30
|
+
| SDK/package pins and lockfiles | Make local and CI feedback reproducible | Locked restore, central versions and SDK feature band |
|
|
31
|
+
| Warnings, style and audit as failures | Surface compiler issues, code drift and known vulnerable dependencies before merge | SDK analysis, format verification and NuGet audit in the verifier |
|
|
32
|
+
| Scoped CI with evidence of routing | Control cost without letting path filters hide meaningful changes | Current CI runs all selected profile checks; selective routing needs its own tests |
|
|
33
|
+
| Concise agent/document routers | Help humans and agents find behavior, architecture and commands without duplicated truths | AGENTS entrypoint and profile navigation |
|
|
34
|
+
| Owned, expiring exceptions | Make deviations deliberate and reversible | Documented process; no expiry automation is claimed |
|
|
35
|
+
|
|
36
|
+
Use [architecture](architecture.md) for dependency direction, [use cases](use-cases.md) for implementation detail, and [guardrails](guardrails.md) for diagnostics, failure consequences and exception ownership.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Tests and development feedback
|
|
2
|
+
|
|
3
|
+
Run `npm run verify:dotnet` from Lighthouse or the generated backend. It performs locked restore, Release build, tests and a deliberately failing-build rehearsal. The repository CI definition runs this command as its .NET job.
|
|
4
|
+
|
|
5
|
+
| Level | Purpose | Reference / cost |
|
|
6
|
+
| --- | --- | --- |
|
|
7
|
+
| Analyzer semantic fixtures | Reject forbidden shapes and allow legitimate code | Compiler in memory; fast |
|
|
8
|
+
| Architecture | Inspect actual exports and assembly dependencies | Compiled assemblies; fast |
|
|
9
|
+
| Functional HTTP | Verify routing, auth, validation and responses through the real ASP.NET pipeline | WebApplicationFactory; no network/services |
|
|
10
|
+
| Persistence | Prove queries, transactions, schema and isolation against the real engine | Add Testcontainers when persistence is introduced |
|
|
11
|
+
| Browser journey | Prove an actual user interaction across the system | Product UI only; slower lane |
|
|
12
|
+
|
|
13
|
+
Choose boundaries according to failure risk. Use domain tests for complex domain rules, functional tests for API/data integration, and a small number of valuable end-to-end journeys. Don't replace functional coverage with mocks or make every PR start a full deployment without evidence that the cost helps.
|
|
14
|
+
|
|
15
|
+
## Local loop
|
|
16
|
+
|
|
17
|
+
```sh
|
|
18
|
+
dotnet run --project src/dotnet/examples/src/root/Lighthouse.Example.Api
|
|
19
|
+
dotnet run --project src/dotnet/examples/src/root/Lighthouse.Example.AppHost
|
|
20
|
+
dotnet test src/dotnet/tests/Lighthouse.Example.Tests -c Release
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Run either the API or AppHost entrypoint. The AppHost starts the API and exposes Aspire's local dashboard; the example has no fake database dependency. Host telemetry/health are development feedback, not proof of a production collector, alerts or durable storage. When adding PostgreSQL or another service, provision it in the local graph, wait for readiness, expose configuration through DI, and add engine-backed tests.
|
|
24
|
+
|
|
25
|
+
Configure `Authentication__Authority` and `Authentication__Audience` with the product's trusted OIDC provider for authenticated manual requests. JWT defaults require issuer/signature/expiry validation and secure metadata. The test scheme and synthetic identity headers are confined to the test assembly. Missing credentials fail closed; the example ships no bypass, identity service or secret. `/health` is a minimal process-readiness route, not proof of data-service readiness.
|
|
26
|
+
|
|
27
|
+
Use user-secrets/environment/approved secret storage for development configuration. Define production logging, redaction, traces/metrics exporters, graceful shutdown, dependency timeouts and recovery according to the product. The in-memory store and lack of full production hardening are explicit example limits.
|
|
28
|
+
|
|
29
|
+
The AppHost pins MessagePack 2.5.303 to resolve [GHSA-qhrr-8q5h-9q3h](https://github.com/MessagePack-CSharp/MessagePack-CSharp/security/advisories/GHSA-qhrr-8q5h-9q3h) while retaining NuGet audit. Revisit the override when the upstream dependency includes the fix.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# One file per use case
|
|
2
|
+
|
|
3
|
+
Read the distributed starter's `CreateEntry.cs` and `GetEntry.cs` examples. Each file owns a concrete behavior rather than a technical layer.
|
|
4
|
+
|
|
5
|
+
| Part | Responsibility | Boundary |
|
|
6
|
+
| --- | --- | --- |
|
|
7
|
+
| Route mapping | URL, binding, authorization policy, cancellation and HTTP outcome | Thin transport adapter |
|
|
8
|
+
| Request / response | External input and output shape | Never expose persistence entities |
|
|
9
|
+
| Command / query | Application intent and its inputs | No HttpContext or IResult |
|
|
10
|
+
| Validator | Structural/business input constraints before mutation | Callable for non-HTTP invocations |
|
|
11
|
+
| Handler | Coordinate the use case and domain/storage work | Internal sealed; returns application data/outcome |
|
|
12
|
+
|
|
13
|
+
Nest these types in the use-case class so related changes remain adjacent. Omit a request DTO where there is no body and no benefit; the query example binds its ID from the route. Keep reusable domain rules in the domain rather than duplicating them across validators.
|
|
14
|
+
|
|
15
|
+
## Completion checklist
|
|
16
|
+
|
|
17
|
+
1. Define the accepted behavior and failure examples before implementing the slice.
|
|
18
|
+
2. Map a Minimal API endpoint and apply its real authorization policy.
|
|
19
|
+
3. Resolve authenticated identity/tenant from trusted context when needed; never trust an owner ID supplied by the body.
|
|
20
|
+
4. Map to a command/query, validate and call an HTTP-independent handler.
|
|
21
|
+
5. Produce explicit success, validation, missing-resource and conflict outcomes as applicable. Hide unexpected exception details behind ProblemDetails and log context without secrets or payload dumps.
|
|
22
|
+
6. Add the cheapest useful tests: domain rules, functional outcomes, authorization failures and persistence boundaries where present.
|
|
23
|
+
7. Run build/analyzers and the required verification command; record any approved exception.
|
|
24
|
+
|
|
25
|
+
The example keeps validation and outcome records local rather than introducing a general results framework. Products can choose an established result/validation library with a pinned version. Cancellation, authorization, logging and transactions still need verification regardless of the library.
|
|
26
|
+
|
|
27
|
+
## Avoid accidental complexity
|
|
28
|
+
|
|
29
|
+
Do not create a controller/service/repository class for every endpoint, a contracts assembly per feature, or a separate read database because a diagram says CQRS. Extract shared code only after a real use case needs it. Keep generated clients/metadata disposable; validate generator inputs, deterministic output and consumer contracts rather than hand-editing generated files.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Lighthouse Expo mobile profile
|
|
2
|
+
|
|
3
|
+
Use this profile when Android or iOS is a real product requirement and the application will run as an Expo and React Native app.
|
|
4
|
+
|
|
5
|
+
## Start here
|
|
6
|
+
|
|
7
|
+
| Need | Read |
|
|
8
|
+
| --- | --- |
|
|
9
|
+
| New mobile application | [adoption](adoption.md) → [guardrails](guardrails.md) → [testing](testing.md) |
|
|
10
|
+
| Add a native capability | [guardrails](guardrails.md) → [testing](testing.md) |
|
|
11
|
+
| Export a web build | [adoption](adoption.md) → [testing](testing.md) |
|
|
12
|
+
|
|
13
|
+
## Defaults
|
|
14
|
+
|
|
15
|
+
Use Expo, React Native, Expo Router, strict TypeScript, TanStack Query and secure storage.
|
|
16
|
+
|
|
17
|
+
Declare deep links, permissions, push notifications and native build targets before implementing a platform capability.
|
|
18
|
+
|
|
19
|
+
Treat web export as an explicit selection with separate evidence. Do not make Expo a hidden layer on top of a React web profile.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: lighthouse-mobile-expo
|
|
3
|
+
description: Apply the Lighthouse Expo mobile profile when a repository selects mobile-expo.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Lighthouse Expo mobile profile
|
|
7
|
+
|
|
8
|
+
Read the mobile profile guide before changing an Expo adopter.
|
|
9
|
+
|
|
10
|
+
Keep features aligned with product capabilities and use TanStack Query for server state. Keep credentials in secure storage and declare every permission and deep link.
|
|
11
|
+
|
|
12
|
+
Treat Android and iOS behavior as native evidence. Add web export only when the product selects it and keep that evidence separate.
|
|
13
|
+
|
|
14
|
+
Run Expo doctor, typecheck, tests and the selected emulator or device journey after a focused change.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Adopt the Lighthouse Expo mobile profile
|
|
2
|
+
|
|
3
|
+
Select `mobile-expo` only when Android or iOS is a product requirement. Select `dotnet-backend` when the product also owns a Lighthouse backend.
|
|
4
|
+
|
|
5
|
+
Set `application.shape` to `mobile` for a mobile-only project or `full-stack` for a mobile application with its backend, and include `expo` in `application.stacks`.
|
|
6
|
+
|
|
7
|
+
Start with authentication, secure storage, one API call and one real interaction in an emulator or device.
|
|
8
|
+
|
|
9
|
+
Choose web export deliberately and keep its browser evidence separate from native evidence.
|
|
10
|
+
|
|
11
|
+
The mobile source, native configuration, permissions and signing policy become product-owned after adoption.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Expo mobile guardrails
|
|
2
|
+
|
|
3
|
+
| Guardrail | Level | Evidence | Failure |
|
|
4
|
+
| --- | --- | --- | --- |
|
|
5
|
+
| TypeScript and lint | Required | Deterministic static checks | The mobile slice stops before integration. |
|
|
6
|
+
| Expo health | Required | Expo doctor and reproducible build | The selected native target is not ready. |
|
|
7
|
+
| Secure storage | Required | Storage and logout test | Credentials remain unverified. |
|
|
8
|
+
| Permissions and deep links | Required | Native configuration and lifecycle tests | The capability remains incomplete. |
|
|
9
|
+
| Authentication and API | Required | Native integration evidence | The first mobile slice is not proven. |
|
|
10
|
+
| Emulator or device journey | Required | Native test evidence | The selected platform remains unverified. |
|
|
11
|
+
| Push notifications | Optional | Product-selected native evidence | No push behavior is assumed. |
|
|
12
|
+
| Web export | Optional | Separate browser build and journey evidence | Native success does not imply web success. |
|
|
13
|
+
|
|
14
|
+
Do not treat a web export as evidence for Android or iOS behavior.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Expo mobile testing
|
|
2
|
+
|
|
3
|
+
| Layer | Purpose | Evidence |
|
|
4
|
+
| --- | --- | --- |
|
|
5
|
+
| Static | TypeScript, lint and Expo configuration | CI output |
|
|
6
|
+
| Unit and component | Feature and interaction behavior | Jest or Vitest with Testing Library |
|
|
7
|
+
| Native integration | Secure storage, permissions, links and API boundary | Emulator or device evidence |
|
|
8
|
+
| Lifecycle | Background, resume, logout, expiry and user change | Native journey evidence |
|
|
9
|
+
| Web export | Selected web behavior | Separate browser evidence |
|
|
10
|
+
|
|
11
|
+
The first vertical slice covers authentication, secure storage, one API call and one real interaction on the selected platform.
|
|
12
|
+
|
|
13
|
+
Keep provider credentials out of fixtures and retain the device or emulator target with the evidence.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Lighthouse .NET MAUI mobile profile
|
|
2
|
+
|
|
3
|
+
Use this profile when Android or iOS is a real product requirement and the application will run as a native .NET MAUI client.
|
|
4
|
+
|
|
5
|
+
## Start here
|
|
6
|
+
|
|
7
|
+
| Need | Read |
|
|
8
|
+
| --- | --- |
|
|
9
|
+
| New native application | [adoption](adoption.md) → [guardrails](guardrails.md) → [testing](testing.md) |
|
|
10
|
+
| Add a device capability | [guardrails](guardrails.md) → [testing](testing.md) |
|
|
11
|
+
| Prepare a release build | [adoption](adoption.md) → [guardrails](guardrails.md) |
|
|
12
|
+
|
|
13
|
+
## Defaults
|
|
14
|
+
|
|
15
|
+
Use C# and XAML with explicit lifecycle, secure storage, deep links, notifications, permissions and device capability boundaries.
|
|
16
|
+
|
|
17
|
+
Use OIDC Authorization Code with PKCE and keep API contracts, permissions, pure business rules, errors, telemetry and visual principles aligned with the product's other clients.
|
|
18
|
+
|
|
19
|
+
Do not reuse React components, browser cookies, web routing, persistence entities, DbContexts or internal handlers.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: lighthouse-mobile-maui
|
|
3
|
+
description: Apply the Lighthouse .NET MAUI mobile profile when a repository selects mobile-maui.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Lighthouse .NET MAUI mobile profile
|
|
7
|
+
|
|
8
|
+
Read the mobile profile guide before changing a .NET MAUI adopter.
|
|
9
|
+
|
|
10
|
+
Keep platform capabilities behind explicit adapters and preserve the boundary between native lifecycle code and pure business rules.
|
|
11
|
+
|
|
12
|
+
Use secure storage, OIDC Authorization Code with PKCE, declared permissions and tested deep links. Keep browser cookies and web routing outside the native client.
|
|
13
|
+
|
|
14
|
+
Run locked restore, analyzers, unit tests and the selected emulator or device journey after a focused change.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Adopt the Lighthouse .NET MAUI mobile profile
|
|
2
|
+
|
|
3
|
+
Select `mobile-maui` only when Android or iOS is a product requirement. Select `dotnet-backend` when the product also owns a Lighthouse backend.
|
|
4
|
+
|
|
5
|
+
Set `application.shape` to `mobile` for a mobile-only project or `full-stack` for a mobile application with its backend, and include `maui` in `application.stacks`.
|
|
6
|
+
|
|
7
|
+
Start with authentication, secure storage, one API call and one real interaction in an emulator or device.
|
|
8
|
+
|
|
9
|
+
Select macOS or Windows targets only when the product requires them. Add packaging and signing only when they are in scope.
|
|
10
|
+
|
|
11
|
+
The mobile source, native configuration, permissions and signing policy become product-owned after adoption.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# .NET MAUI mobile guardrails
|
|
2
|
+
|
|
3
|
+
| Guardrail | Level | Evidence | Failure |
|
|
4
|
+
| --- | --- | --- | --- |
|
|
5
|
+
| Locked restore and build | Required | Deterministic restore and build per target | The selected native target is not reproducible. |
|
|
6
|
+
| Analyzers and format | Required | Static checks and format verification | The mobile slice stops before integration. |
|
|
7
|
+
| Secure storage and authentication | Required | OIDC, storage, logout and expiry tests | Credentials or session behavior remains unverified. |
|
|
8
|
+
| Permissions and deep links | Required | Native configuration and lifecycle tests | The capability remains incomplete. |
|
|
9
|
+
| Emulator or device journey | Required | Native functional evidence | The selected platform remains unverified. |
|
|
10
|
+
| Notifications, camera and files | Optional | Product-selected native evidence | No device capability is assumed. |
|
|
11
|
+
| Packaging and signing | Optional | Product-selected release evidence | No release signing is assumed. |
|
|
12
|
+
|
|
13
|
+
Share contracts, permissions, pure rules, errors, telemetry and visual principles deliberately. Keep web routing, cookies, React components, persistence entities and internal backend handlers outside the client.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# .NET MAUI mobile testing
|
|
2
|
+
|
|
3
|
+
| Layer | Purpose | Evidence |
|
|
4
|
+
| --- | --- | --- |
|
|
5
|
+
| Restore and build | Prove each selected target resolves and compiles | Locked CI output |
|
|
6
|
+
| Unit | Exercise pure rules and client behavior | .NET test output |
|
|
7
|
+
| Integration | Exercise API, authentication and secure storage boundaries | Approved test host or device evidence |
|
|
8
|
+
| Lifecycle | Prove background, resume, logout, expiry and user change | Emulator or device journey |
|
|
9
|
+
| Device capability | Prove selected permissions, links, notifications, camera or files | Target-specific evidence |
|
|
10
|
+
|
|
11
|
+
The first vertical slice covers authentication, secure storage, one API call and one real interaction on the selected platform.
|
|
12
|
+
|
|
13
|
+
Keep signing material and provider credentials outside fixtures. Retain the target platform and build configuration with the evidence.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Lighthouse PWA capability
|
|
2
|
+
|
|
3
|
+
Use this capability when a React web application has a real installability or offline requirement.
|
|
4
|
+
|
|
5
|
+
## Start here
|
|
6
|
+
|
|
7
|
+
| Need | Read |
|
|
8
|
+
| --- | --- |
|
|
9
|
+
| Public installable web app | [adoption](adoption.md) → [guardrails](guardrails.md) |
|
|
10
|
+
| Authenticated PWA | [adoption](adoption.md) → [offline policy](offline.md) |
|
|
11
|
+
| Diagnose an update problem | [guardrails](guardrails.md) → [testing](testing.md) |
|
|
12
|
+
|
|
13
|
+
## Defaults
|
|
14
|
+
|
|
15
|
+
Declare the manifest, icons, service worker, asset cache, update strategy and offline behavior as part of the product surface.
|
|
16
|
+
|
|
17
|
+
Cache assets separately from navigation and private data. Do not cache private APIs automatically and do not store tokens in browser storage.
|
|
18
|
+
|
|
19
|
+
An authenticated PWA keeps the `web-bff` session boundary; installability does not change authentication ownership.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: lighthouse-pwa
|
|
3
|
+
description: Apply the Lighthouse PWA capability when a repository selects pwa-capability.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Lighthouse PWA capability
|
|
7
|
+
|
|
8
|
+
Read the PWA guide before changing an adopter's installability or offline behavior.
|
|
9
|
+
|
|
10
|
+
Separate asset, navigation and private-data caching. Declare the bounded contexts that work offline and the actions that need the network.
|
|
11
|
+
|
|
12
|
+
Keep authenticated sessions on the web BFF contract. Keep tokens out of browser storage and test logout, expiry and user changes.
|
|
13
|
+
|
|
14
|
+
Run install, update, cache and browser evidence after a focused change. Treat a missing update or recovery test as an incomplete capability.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Adopt the Lighthouse PWA capability
|
|
2
|
+
|
|
3
|
+
Select `pwa-capability` with `react-web-platform` when installability, asset caching or a declared offline journey is a product requirement.
|
|
4
|
+
|
|
5
|
+
Choose the bounded contexts that work offline and record which actions remain online-only.
|
|
6
|
+
|
|
7
|
+
Define the update and recovery behavior before enabling a service worker in production. Test a fresh install, an update, logout, session expiry and a user change.
|
|
8
|
+
|
|
9
|
+
Keep the application source, manifest values, icons and service-worker implementation product-owned after adoption.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# PWA guardrails
|
|
2
|
+
|
|
3
|
+
| Guardrail | Level | Evidence | Failure |
|
|
4
|
+
| --- | --- | --- | --- |
|
|
5
|
+
| Manifest and icons | Required | Deterministic build and installability check | The capability is not installable. |
|
|
6
|
+
| Asset cache | Required | Service-worker inspection and browser test | The cache contract is incomplete. |
|
|
7
|
+
| Update strategy | Required | Fresh-install and update journey | A stale application can remain active without a recovery path. |
|
|
8
|
+
| Offline scope | Required | Declared bounded contexts and behavior review | Offline behavior remains ambiguous. |
|
|
9
|
+
| Private API cache | Required | Static or review check | The capability stops until private-data caching is explicitly designed. |
|
|
10
|
+
| Session lifecycle | Required for authenticated apps | Logout, expiry and user-change journeys | The session boundary remains unverified. |
|
|
11
|
+
| Push | Optional | Product-selected permission and delivery evidence | No push behavior is assumed. |
|
|
12
|
+
|
|
13
|
+
Do not enable offline-first behavior by convention. Make the offline boundary a product decision and keep it narrow.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# PWA offline policy
|
|
2
|
+
|
|
3
|
+
Classify each bounded context as online-only, read-only offline or read-write offline before adding data caching.
|
|
4
|
+
|
|
5
|
+
Keep assets, navigation and data caches separate so an update can invalidate one policy without changing the others.
|
|
6
|
+
|
|
7
|
+
Read-only offline journeys need an explicit freshness rule and a visible stale state.
|
|
8
|
+
|
|
9
|
+
Read-write offline journeys need conflict handling, replay rules, authentication recovery and evidence for a changed user.
|
|
10
|
+
|
|
11
|
+
Private API responses remain online-only until the product and architecture define encryption, retention, invalidation and conflict behavior.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# PWA testing
|
|
2
|
+
|
|
3
|
+
| Journey | Evidence |
|
|
4
|
+
| --- | --- |
|
|
5
|
+
| Fresh install | Manifest, icon and service-worker registration check |
|
|
6
|
+
| Asset update | New revision replaces the cached revision |
|
|
7
|
+
| Navigation offline | Declared navigation fallback behaves as designed |
|
|
8
|
+
| Private data | No undeclared API response enters a cache |
|
|
9
|
+
| Logout and expiry | Authenticated cache and session state are cleared or blocked |
|
|
10
|
+
| User change | The next user cannot observe the previous user's data |
|
|
11
|
+
| Push, when selected | Permission, delivery and revocation evidence |
|
|
12
|
+
|
|
13
|
+
Run the journeys in a real browser context with a clean profile and a second revision of the application.
|
|
14
|
+
|
|
15
|
+
A successful service-worker registration alone is not evidence that the update and data policies work.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Lighthouse React web profile
|
|
2
|
+
|
|
3
|
+
Use this profile for React applications that need a predictable browser boundary, feature-oriented source and evidence for the journeys users rely on.
|
|
4
|
+
|
|
5
|
+
## Start here
|
|
6
|
+
|
|
7
|
+
| Need | Read |
|
|
8
|
+
| --- | --- |
|
|
9
|
+
| New web application | [structure](structure.md) → [guardrails](guardrails.md) → [testing](testing.md) |
|
|
10
|
+
| Existing web application | [adoption](adoption.md) → [structure](structure.md) |
|
|
11
|
+
| Implement a feature | [structure](structure.md) → [testing](testing.md) |
|
|
12
|
+
| Diagnose a failed check | [guardrails](guardrails.md) |
|
|
13
|
+
|
|
14
|
+
## Defaults
|
|
15
|
+
|
|
16
|
+
Use React and strict TypeScript with thin routes, an app shell and feature slices aligned with bounded contexts and backend use cases.
|
|
17
|
+
|
|
18
|
+
Use TanStack Query for server state and keep local state local; put filters, pagination and meaningful navigation state in the URL.
|
|
19
|
+
|
|
20
|
+
Use explicit API contracts, visual-theme tokens, Testing Library, Vitest, Playwright and axe for the applicable surfaces.
|
|
21
|
+
|
|
22
|
+
Add form, schema, mock or client-generation libraries only when a real feature requires them and the contract is stable.
|
|
23
|
+
|
|
24
|
+
The profile does not create a runtime component library or turn shared folders into a technical-layer architecture.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: lighthouse-react-web
|
|
3
|
+
description: Apply the Lighthouse React web profile when a repository selects react-web-platform.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Lighthouse React web profile
|
|
7
|
+
|
|
8
|
+
Read the profile guide before changing a React adopter.
|
|
9
|
+
|
|
10
|
+
Keep routes thin and organize behavior by feature and bounded context. Put screens, API calls, queries, mutations, components, types and tests beside the feature that owns them.
|
|
11
|
+
|
|
12
|
+
Use TanStack Query for server state. Keep local UI state local and put filters, pagination and meaningful navigation state in the URL.
|
|
13
|
+
|
|
14
|
+
Use explicit API contracts and render loading, empty, error, disabled and validation states for each interactive surface.
|
|
15
|
+
|
|
16
|
+
Run the project's typecheck, lint, format, build, unit and browser checks after a focused change. Use axe evidence for critical surfaces.
|
|
17
|
+
|
|
18
|
+
Application code, tests, dependencies and build policy become adopter-owned after creation. Do not overwrite them from the profile.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Adopt the Lighthouse React web profile
|
|
2
|
+
|
|
3
|
+
## New application
|
|
4
|
+
|
|
5
|
+
Select `react-web-platform` with `visual-theme`, set `application.shape` to `frontend` or `full-stack` and set `application.stacks` to include `react`.
|
|
6
|
+
|
|
7
|
+
Run `lighthouse profiles --format json` before writing application code and keep the reported commands in the repository's normal verification loop.
|
|
8
|
+
|
|
9
|
+
## Existing application
|
|
10
|
+
|
|
11
|
+
Inventory routing, session, API contracts, server state, feature boundaries, interaction states, accessibility evidence, tests and build output before moving files.
|
|
12
|
+
|
|
13
|
+
Map the existing implementation to the profile and record project-owned exceptions where a move would change behavior or ownership.
|
|
14
|
+
|
|
15
|
+
Adopt one user journey first: session, authenticated screen, query, mutation, loading, empty, error and authentication failure.
|
|
16
|
+
|
|
17
|
+
The application owns its source, tests, dependencies and build configuration after adoption; Lighthouse owns only the generated profile guidance and declared projections.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# React web guardrails
|
|
2
|
+
|
|
3
|
+
| Guardrail | Level | Evidence | Failure |
|
|
4
|
+
| --- | --- | --- | --- |
|
|
5
|
+
| Strict TypeScript | Required | Deterministic typecheck | The profile is not ready for delivery. |
|
|
6
|
+
| Lint and format | Required | Deterministic lint and format checks | The change stops before integration. |
|
|
7
|
+
| Reproducible build | Required | Deterministic production build | The application cannot be released from this revision. |
|
|
8
|
+
| Unit and component tests | Required | Deterministic Vitest and Testing Library checks | The affected slice needs repair. |
|
|
9
|
+
| Critical browser journeys | Required | Playwright evidence | The journey remains unverified. |
|
|
10
|
+
| Accessibility on critical surfaces | Required | axe evidence and human review where needed | The surface remains pending review. |
|
|
11
|
+
| Import boundaries | Recommended | Static or architectural check | Record a project-owned exception with an owner and review date. |
|
|
12
|
+
| Visual drift | Recommended | Visual evidence against the selected theme | Review the changed surface before accepting it. |
|
|
13
|
+
| Performance budget | Optional | Project-selected budget check | Record why the budget is not applicable. |
|
|
14
|
+
|
|
15
|
+
A public web application may call a public API directly when that decision is recorded; an authenticated web application selects `web-bff` by default.
|
|
16
|
+
|
|
17
|
+
Do not store access or refresh tokens in localStorage, sessionStorage or IndexedDB. The BFF profile owns the authenticated browser session contract.
|