Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
512 commits
Select commit Hold shift + click to select a range
9696bfa
docs: include Microsoft.Restier.AspNetCore.NSwag in docsproj sources
May 1, 2026
5405887
docs: write guides/server/nswag.mdx
May 1, 2026
6bd974c
docs: link Swagger page to NSwag as the recommended alternative
May 1, 2026
4baf7bb
docs: list NSwag ahead of Swagger in Server guide nav
May 1, 2026
2b7c67a
docs: add README for Microsoft.Restier.AspNetCore.NSwag
May 1, 2026
f7a6a66
fix: UseRestierNSwagUI now includes user-registered NSwag documents i…
May 1, 2026
2151c16
docs: write OpenAPI annotation attributes design spec
May 1, 2026
b61eac5
docs: write OpenAPI annotation attributes implementation plan
May 1, 2026
c175c2a
feat: add empty ConventionBasedAnnotationModelBuilder + register in c…
May 1, 2026
1bde7b8
feat: emit Core.V1.Description from [Description] on entity types
May 2, 2026
45fad07
refactor: preserve non-EdmModel inner result; minor test cleanup
May 2, 2026
7ef7134
feat: emit Core.V1.Description from [Description] on properties
May 2, 2026
d1076a8
test: lock in Core.V1.Description on complex types
May 2, 2026
be817e2
feat: emit Core.V1.Description from [Description] on operations
May 2, 2026
02fbba6
feat: emit Core.V1.Computed from [DatabaseGenerated]
May 2, 2026
f78aeb9
feat: emit Core.V1.Immutable from [ReadOnly(true)]
May 2, 2026
d413588
feat: emit Validation.Min/Max from [Range], typed by EDM primitive kind
May 2, 2026
d07a7d5
feat: emit Validation.Pattern from [RegularExpression]
May 2, 2026
280c4cd
test: lock in idempotence, null guards, and MaxLength-skip behavior
May 2, 2026
45c3ce9
test: lock in operation scan invariants (inherited, non-public, speci…
May 2, 2026
21f78ea
test: harden IsSpecialName test to genuinely exercise the filter
May 2, 2026
f239b2f
test: add annotated test scenario (entity, context, API)
May 2, 2026
742a2f9
test: add AnnotatedApi metadata baseline integration test
May 2, 2026
cd328be
test: assert submit-pipeline behavior change from Computed/Immutable
May 2, 2026
acf2765
docs: write guides/server/openapi-annotations.mdx
May 2, 2026
c15fa14
docs: add openapi-annotations to nav, cross-link from related pages
May 2, 2026
bb0bd52
docs: fix openapi-annotations accuracy (PUT bodies, safer opt-out cas…
May 3, 2026
5cc5c9a
fix: use EdmClrPropertyMapper for property lookup; correct opt-out re…
May 3, 2026
ce30349
docs: write API versioning design spec
May 3, 2026
97809ea
docs: revise API versioning spec per review
May 3, 2026
5285f71
docs: fix three follow-up findings in API versioning spec
May 3, 2026
af3f968
docs: tighten three more findings in API versioning spec
May 3, 2026
82a8542
docs: address four more findings in API versioning spec
May 3, 2026
7b63286
docs: write API versioning implementation plan
May 4, 2026
84db40e
docs: address six findings in API versioning plan + spec
May 4, 2026
5037a33
feat: add IRestierApiVersionRegistry / RestierApiVersionDescriptor co…
May 4, 2026
c6ad584
chore: add Microsoft.Restier.AspNetCore.Versioning project skeleton
May 4, 2026
5780320
chore: add Microsoft.Restier.Tests.AspNetCore.Versioning project skel…
May 4, 2026
abbe56c
chore: wire Versioning + tests into RESTier.slnx
May 4, 2026
e56132a
feat: add ApiVersionSegmentFormatters with Major and MajorMinor
May 4, 2026
99a6207
feat: add RestierVersioningOptions (segment formatter, explicit prefi…
May 4, 2026
030362f
feat: add ApiVersionAttributeReader
May 4, 2026
5366981
feat: add RestierApiVersionRegistry concrete implementation
May 4, 2026
ecd6a36
feat: add IRestierApiVersioningBuilder + concrete implementation
May 4, 2026
77ff626
feat: add RestierApiVersioningOptionsConfigurator
May 4, 2026
dc12525
feat: add AddRestierApiVersioning entry point
May 4, 2026
2987184
feat: implement RestierApiVersionDescriptionProvider
May 4, 2026
5cae92e
feat: add RestierVersionHeadersMiddleware
May 4, 2026
63a06c5
feat: add UseRestierVersionHeaders extension
May 4, 2026
9865cdf
test: add versioned-API integration test fixture
May 4, 2026
c50b4fa
test: cover versioned $metadata and per-version GET 404
May 4, 2026
abd0459
test: integration coverage for versioning response headers
May 4, 2026
3abee6e
test: cover versioned $batch routing for V1 and V2
May 4, 2026
3c7d1b1
feat(nswag): registry-aware OpenAPI doc resolution
May 4, 2026
be78b53
feat(nswag): registry-aware ReDoc and Swagger UI helpers
May 4, 2026
0357382
test: cross-project NSwag + Versioning integration
May 4, 2026
00a42dc
feat(swagger): registry-aware OpenAPI doc resolution
May 4, 2026
5dcd76e
feat(swagger): registry-aware UseRestierSwaggerUI
May 4, 2026
a190110
test: cross-project Swagger + Versioning integration
May 4, 2026
a6a468d
feat(samples): scaffold NorthwindVersioned sample (data + API classes)
May 4, 2026
fd316de
feat(samples): wire NorthwindVersioned Startup + add to RESTier.slnx
May 4, 2026
4fe4c05
docs: include Microsoft.Restier.AspNetCore.Versioning in docsproj sou…
May 4, 2026
3555c54
docs: write guides/server/api-versioning.mdx
May 4, 2026
7bf6d84
docs: add api-versioning to nav, cross-link from nswag/swagger,
May 4, 2026
ee20621
fix(versioning): GroupName collision detection + basePrefix normaliza…
May 5, 2026
aae2f05
docs: sync spec + plan with GroupNameFormatter and basePrefix normali…
May 5, 2026
d6b4cc4
docs: add reverse-proxy alternative to API versioning guide
May 5, 2026
5569ebc
docs: annotate nswag plan with cancellationToken + ApiBase notes
May 5, 2026
dcaa386
test: cover collection-valued @odata.bind inside $batch (#663)
May 5, 2026
943b7c9
docs: add multi-tenancy design spec (DB-per-tenant via middleware)
May 5, 2026
c2b9d74
docs: address four findings in multi-tenancy spec
May 5, 2026
54bf0bb
docs: add multi-tenancy implementation plan
May 5, 2026
c6ae5fd
test: scaffold multi-tenancy support types
May 5, 2026
8a4837c
docs: correct MultiTenantApi constructor in plan to match convention
May 5, 2026
937ab2d
test: scope multi-tenancy scaffolding types as internal
May 5, 2026
148ff47
docs: scope multi-tenancy plan scaffolding types as internal
May 5, 2026
ce9fd35
test: add PathSegmentTenantResolutionMiddleware
May 5, 2026
db1f35c
docs: revert plan visibility back to public with rationale
May 5, 2026
849acc1
test: dispose ServiceProvider/IServiceScope in middleware tests
May 5, 2026
8e97844
test: add multi-tenancy integration test fixture + Acme query
May 5, 2026
f3de613
docs: update plan with the DbContext model-build null-guard
May 5, 2026
b0b4fcb
test: comment why MultiTenancyTests bridges via http.RequestServices
May 5, 2026
0e7aa40
test: add Globex tenant case to multi-tenancy tests
May 5, 2026
18d9d0e
test: assert cross-tenant POST does not leak to other tenants
May 5, 2026
8db5540
test: verify @odata.context preserves tenant prefix via PathBase
May 5, 2026
21a7fde
test: assert unknown tenant returns 400 from middleware validation
May 5, 2026
47a587f
test: tidy MultiTenancyTests using order and POST status assertion
May 5, 2026
5cc2fd3
docs: fix SharedDbApi sample in multi-tenancy plan
May 5, 2026
e81132e
docs: add Multi-Tenancy guide page
May 5, 2026
861e816
docs: warn readers about OnFilter entity-set-name footgun
May 5, 2026
53ae0ec
docs: register Multi-Tenancy page in nav
May 5, 2026
74d67ec
docs: fix IConnectionStringProvider registration recipe and spec
May 5, 2026
3dc4c46
refactor: drop redundant IConnectionStringProvider route registration
May 5, 2026
a205f8e
docs: add sidebar icons to multi-tenancy and api-versioning pages
May 5, 2026
219e614
docs: add spec for spatial types round-trip (issue #673)
May 6, 2026
ddb0383
docs: revise spatial types spec after review
May 6, 2026
53f2da3
docs: revise spatial types spec for second-round review
May 6, 2026
66eb299
docs: revise spatial types spec for third-round review
May 6, 2026
3c4e334
docs: revise spatial types spec for fourth-round review
May 7, 2026
b55cb0b
docs: add implementation plan for spatial types round-trip
May 7, 2026
b7d391d
feat(core): add SpatialGenus enum for spatial type families
May 7, 2026
b6c1da3
feat(core): add [Spatial] attribute for EDM type opt-in
May 7, 2026
c680591
feat(core): add ISpatialTypeConverter interface
May 7, 2026
4b2431f
feat(core): add ISpatialModelMetadataProvider interface
May 7, 2026
93d44b1
feat(core): add SridPrefixHelpers for SQL Server WKT dialect mediation
May 7, 2026
1c11998
feat(ef6.spatial): scaffold Microsoft.Restier.EntityFramework.Spatial…
May 7, 2026
c63aedb
test(ef6.spatial): scaffold test project
May 7, 2026
515b4b8
feat(ef6.spatial): add DbSpatialConverter with Geography Point round-…
May 11, 2026
5286e72
test(ef6.spatial): broaden DbSpatialConverter coverage (Polygon, Z, S…
May 11, 2026
4df3f71
feat(ef6.spatial): add DbSpatialModelMetadataProvider
May 11, 2026
da48b6d
feat(ef6.spatial): add AddRestierSpatial DI extension
May 11, 2026
524b017
feat(efcore.spatial): scaffold Microsoft.Restier.EntityFrameworkCore.…
May 11, 2026
428331b
test(efcore.spatial): scaffold test project
May 11, 2026
30d9f98
feat(efcore.spatial): add NtsSpatialConverter for Microsoft.Spatial <…
May 11, 2026
3f4d672
feat(efcore.spatial): add NtsSpatialModelMetadataProvider with column…
May 11, 2026
b900853
feat(efcore.spatial): add AddRestierSpatial DI extension
May 11, 2026
7dc6083
feat(ef.shared): add SpatialModelConvention capture phase
May 11, 2026
b9d3782
feat(ef.shared): add SpatialModelConvention augment phase with naming…
May 11, 2026
bbdf002
test(efcore.spatial): assert [Spatial] validation against non-Spatial…
May 11, 2026
f3ed15a
feat(ef.shared): EFModelBuilder invokes SpatialModelConvention phases…
May 11, 2026
b5a37fe
feat(aspnetcore): EdmHelpers.GetPrimitiveTypeKind recognizes Microsof…
May 11, 2026
72624f7
feat(aspnetcore): RestierPayloadValueConverter dispatches spatial bra…
May 11, 2026
76cfceb
feat(ef6): EFChangeSetInitializer dispatches spatial writes to ISpati…
May 11, 2026
2cf875a
feat(efcore): EFChangeSetInitializer dispatches spatial writes to ISp…
May 11, 2026
555c9fd
test(library): wire spatial DI and add SqlServer NTS package referenc…
May 12, 2026
a866ffd
test(library): add SpatialPlace test entity (flavor-conditional)
May 12, 2026
466b544
test(integration): spatial round-trip end-to-end + regenerated EDM ba…
May 12, 2026
48802ef
refactor(ef6): delete obsolete GeographyConverter (replaced by DbSpat…
May 12, 2026
87f311a
feat(samples): add spatial HomeLocation to the Postgres sample
May 12, 2026
d2f2885
docs: add Spatial Types guide page
May 12, 2026
815a143
fix: unblock the EF6/EFCore integration test suite on .NET 5+
May 13, 2026
6b9c35b
test(ef6): wipe+reseed shared SQL Server DB once per process
May 13, 2026
7f16ccd
docs(plans): add EF6 spatial tests dotMorten shim plan
May 13, 2026
b4a9e6b
docs(plans): revise EF6 spatial plan after dotMorten falsification spike
May 14, 2026
18fd230
test(ef6-spatial): unskip round-trip tests via Microsoft.SqlServer.Ty…
May 14, 2026
1488374
test(ef6-spatial): comment why GeodeticNativeAvailable catches Exception
May 14, 2026
f1c7860
docs(spatial): explain EF6 + .NET 5+ Microsoft.SqlServer.Types requir…
May 14, 2026
19ca16c
docs(spatial): address code review on EF6/.NET 5+ section
May 14, 2026
016cf2d
fix(aspnetcore): propagate ODataOptions.TimeZone to filter binder (#704)
May 15, 2026
ffb4cba
docs(specs): design Spec B — server-side geo.* filter translation
May 15, 2026
54db99b
docs(specs): revise Spec B after first code review
May 15, 2026
541d82c
docs(specs): move Spec B binder registration to Microsoft.Restier.Asp…
May 15, 2026
46436e3
docs(plans): add Spec B implementation plan
May 15, 2026
1ae8835
feat(spatial-filter): add resource strings for filter-binder errors
May 15, 2026
852e985
fix(spatial-filter): reorder NoConverterForStorageType placeholders +…
May 15, 2026
3855e6c
feat(spatial-filter): add RestierSpatialFilterBinder skeleton
May 15, 2026
f2faabc
style(spatial-filter): match .editorconfig + namespace pattern in ske…
May 15, 2026
a8ab19b
feat(spatial-filter): wire RestierSpatialFilterBinder into AddRouteCo…
May 15, 2026
7487390
refactor(query-builder): accept optional IFilterBinder via ctor
May 15, 2026
14092fb
refactor(controller): pass DI-resolved IFilterBinder to RestierQueryB…
May 15, 2026
9d19a3a
style(controller): drop ?. on GetRouteServices for IFilterBinder lookup
May 15, 2026
eceb5f7
test(spatial-filter): add RouteLine LineString to SpatialPlace fixture
May 15, 2026
65d82a5
fix(library-fixture): pin RouteLine column type to geography
May 15, 2026
24d5098
test(spatial-filter): add .Spatial ProjectReferences to Tests.AspNetC…
May 15, 2026
db13a7d
feat(spatial-filter): translate geo.length to storage Length property…
May 15, 2026
aca5b4f
docs(spatial-filter): make RestierSpatialFilterBinder XML docs honest
May 15, 2026
3593c89
feat(spatial-filter): translate geo.distance via storage Distance method
May 15, 2026
f8d8475
fix(spatial-filter): wrap NotSupportedException from converter as ODa…
May 15, 2026
a7c9faa
feat(spatial-filter): translate geo.intersects via storage Intersects…
May 15, 2026
f39c29d
test(spatial-filter): assert unknown geo.* function names still reject
May 15, 2026
21cd8f6
docs(specs/plans): record parser-pre-validates-genus finding for Spec B
May 15, 2026
24e2126
test(spatial-filter): pin no-converters-registered diagnostic
May 15, 2026
029fbf8
docs(specs/plans): record non-EPSG-CRS path unreachable finding for S…
May 15, 2026
da9d54d
fix(spatial-filter): make geo.* LINQ output EF-Core-translatable
May 15, 2026
d180f5e
test(spatial-filter): add geo.* integration coverage with CLR-aware s…
May 15, 2026
ad142a2
docs(spatial): document server-side geo.* filter translation
May 15, 2026
c60b9f4
fix(spatial-filter): use lowered0.Type as both-literal hint for lowered1
May 15, 2026
3f694a0
test(query-builder): update FilterBinderResolutionTests ctor calls fo…
May 15, 2026
56fe9f6
docs: refresh spatial binder remarks + document TimeZone propagation …
May 15, 2026
4b880bd
docs(spec): allow [AllowAnonymous]/[Authorize] on RESTier API surfaces
May 15, 2026
248317a
docs(spec): address review on cache key + test harness auth wiring
May 15, 2026
905562e
docs(spec): rename remaining BuildWrappedEndpoint refs to DiscoverAtt…
May 15, 2026
450d83f
docs(plan): implementation plan for [AllowAnonymous]/[Authorize] on R…
May 15, 2026
a177f70
refactor(routing): RestierRouteMarker carries the registered API type
May 15, 2026
b4c3564
feat(routing): add ComputeTargetKey helper for authorization metadata…
May 18, 2026
8ae8b4a
feat(routing): add DiscoverAttributes; drop resource-property surface
May 18, 2026
55cbcd0
feat(routing): implement IEndpointSelectorPolicy.AppliesToEndpoints
May 18, 2026
1ad24e4
feat(routing): implement RestierAuthorizationMetadataPolicy.ApplyAsync
May 18, 2026
09b59d0
feat: wire authorization metadata policy through AddRestier; integrat…
May 18, 2026
8c6b231
docs: document [AllowAnonymous] / [Authorize] on RESTier API surfaces
May 18, 2026
4494045
docs+comments: fix [AllowAnonymous] precedence trap and operation ver…
May 18, 2026
d1ea9ec
docs(comment): RestierRouteMarker is route-services only, not endpoin…
May 18, 2026
08254d0
test(aspnetcore): refresh LibraryApi metadata baselines for SpatialPl…
May 18, 2026
6025c88
fix(spatial-filter): normalize geo.length PropertyInfo to base Geomet…
May 18, 2026
954f116
feat(core): add HasRecursiveExpand and AllowNoTracking hints to Query…
May 19, 2026
6be8719
feat(core): add IExpandCycleDetector interface
May 19, 2026
2fbd788
feat(core): add DefaultExpandCycleDetector
May 19, 2026
3c000de
test(core): exercise inheritance walk in expand cycle detector
May 19, 2026
02ce1cf
feat(core): register IExpandCycleDetector default in core DI
May 19, 2026
34a63de
feat(aspnetcore): opt HTTP reads into no-tracking + compute expand-cy…
May 19, 2026
3bfbf3f
docs(spec): design for RestierRouteOptions and opt-in conformance
May 19, 2026
bffbff1
feat(ef): introduce RestierEFTrackingBehavior and RestierEFOptions
May 19, 2026
096f5a5
feat(ef): register default RestierEFOptions in shared DI
May 19, 2026
5a51131
feat(ef6): add AddEF6ProviderServices overloads with RestierEFOptions
May 19, 2026
ec00fc5
feat(efcore): add AddEFCoreProviderServices overloads with RestierEFO…
May 19, 2026
c865c82
feat(ef): apply no-tracking by default in EFQueryExpressionSourcer
May 19, 2026
6d04486
docs(spec): address review findings on conformance-options design
May 19, 2026
61611e0
test(efcore): unit tests for RestierEFOptions tracking behavior
May 19, 2026
991ae95
test(ef6): unit tests for RestierEFOptions tracking behavior
May 19, 2026
83f8c46
docs(plan): implementation plan for RestierRouteOptions + conformance…
May 19, 2026
57a1db6
feat(core): add RestierConformanceOptions for opt-in spec strictness
May 19, 2026
ae03224
feat(core): add RestierRouteOptions bag for per-route configuration
May 19, 2026
24d855e
feat(aspnetcore)!: replace AddRestierRoute overloads with options-bag…
May 19, 2026
4a9dfac
docs(aspnetcore): correct stale summary on AddRestierRoute overload A
May 19, 2026
4f22bea
feat(breakdance): flow Action<RestierRouteOptions> through test helpers
May 19, 2026
ef1bb0d
feat(breakdance): thread configureOptions through GetTestableInjected…
May 19, 2026
4e6590e
sample: migrate AddRestierRoute calls to new options-bag form
May 19, 2026
e63f377
docs: tracking-behavior guide, release notes, api-reference regen
May 19, 2026
0b855b5
docs: drop hedge in performance.mdx; add the implementation plan
May 19, 2026
8031666
feat(versioning)!: switch AddVersion to Action<RestierRouteOptions>
May 19, 2026
1c2e00e
feat(controller): opt-in 404 for collection nav from missing parent
May 19, 2026
f8b9c46
test: cover opt-in collection-nav 404 conformance toggle (#735)
May 19, 2026
ee2d57a
test(rename): drop misleading 'Empty' from existing-parent strict test
May 19, 2026
764ac70
docs: add conformance-options guide and RestierRouteOptions migration…
May 19, 2026
3cc2445
docs: migrate AddRestierRoute samples to options-bag form
May 19, 2026
a8b7e13
fix(aspnetcore)+test: opt bound-function GET binding source into no-t…
May 19, 2026
405b9f0
test(ef): direct sourcer tests covering EF6 recursive-expand fallback
May 19, 2026
5ca32c4
fix: address final review findings on conformance-options branch
May 19, 2026
10d5d7a
fix(test-infra): force-close pooled connections before EF6 SeedDataba…
May 19, 2026
7a928b0
test(aspnetcore): opt BoundFunctions tests into TrackAll for intercep…
May 19, 2026
5ce1cc8
fix(controller): apply StrictMissingParentForCollections to $count too
May 19, 2026
4e5893c
docs: document $count coverage of StrictMissingParentForCollections
May 19, 2026
1fbd9ea
test(ef6): HTTP-level no-tracking tests via Breakdance
May 19, 2026
7f45d8d
Merge branch 'feature/vnext' into worktree-issue-735-empty-set
May 19, 2026
8f51224
fix(ef6): null-safe rewrite of in-memory SelectExpand projection
May 19, 2026
777ea3b
test(deep-insert): configure MaxDepth via RestierRouteOptions bag
May 19, 2026
da37f5d
docs(spec): design for keyless EF views as read-only RESTier resources
May 19, 2026
a94d2b9
docs(spec): revise keyless-views design after code-review pushback
May 19, 2026
00906d9
docs(spec): add documentation deliverable + dedicated follow-ups section
May 19, 2026
260bbfd
docs(plan): implementation plan for keyless EF views (#741)
May 19, 2026
ac67ac6
docs(plan+spec): four corrections after second review round
May 19, 2026
9ca7444
docs(plan+spec): three corrections after third review round
May 19, 2026
f4029a2
docs(plan): fix Ensure helper method name (NotNullOrWhiteSpace, not N…
May 19, 2026
29a9331
feat(core): add KeylessViewEntry DTO for keyless-view dispatch
May 19, 2026
85928ba
feat(core): add KeylessViewRegistry with duplicate-name guard
May 19, 2026
4794a55
feat(aspnetcore): bridge KeylessViewRegistry across model-build SP
May 19, 2026
2a4f35a
feat(ef): inject KeylessViewRegistry into shared EFModelBuilder
May 19, 2026
57ee829
feat(ef): demote keyless types to ComplexType + FunctionImport (EFCore)
May 19, 2026
cad37fd
test(efcore): verify keyless views become ComplexType + FunctionImport
May 19, 2026
a9b7b37
feat(aspnetcore): dispatch keyless-view function imports via registry
May 19, 2026
b1f0e19
feat(aspnetcore): return 405 for DELETE/PUT/PATCH on function imports
May 19, 2026
2e5f7f1
refactor(tests): move LibraryWithViews fixtures to shared
May 19, 2026
e084f53
test(infra): seed LibraryWithViewsContext via SeedDatabase helper (EF…
May 19, 2026
8c3c84c
feat(ef6): emit source factories + normalise empty key lists
May 19, 2026
6b27750
test(efcore): end-to-end coverage for keyless-view function imports
May 19, 2026
03c7679
refactor(keyless-views): reuse LibraryContext instead of separate fix…
May 19, 2026
6934b55
refactor(keyless-views): scope to EFCore only; remove EF6 path
May 19, 2026
84f5a0b
docs(server): add Keyless Views guide + cross-links + release-notes stub
May 19, 2026
7776e5d
fix(keyless-views): fire operation-filter pipeline + pin naming behav…
May 19, 2026
57968eb
fix(keyless-views): initialise ParameterValues before filter pipeline
May 19, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
Binary file added .DS_Store
Binary file not shown.
12 changes: 0 additions & 12 deletions .claude/settings.local.json

This file was deleted.

File renamed without changes.
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -329,3 +329,9 @@ ASALocalRun/
# MFractors (Xamarin productivity tool) working folder
.mfractor/
/docs/msdocs/.vscode
/docs/msdocs/_site/

# DotNetDocs SDK regenerates this on build
src/Microsoft.Restier.Docs/api-reference/
# DotNetDocs SDK writes this as a Debug-build debug dump (not config)
src/Microsoft.Restier.Docs/assembly-list.txt
119 changes: 119 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Project Overview

Microsoft RESTier is an OData V4 API development framework for building standardized RESTful services on .NET. It is the spiritual successor to WCF Data Services, providing convention-based query interception and data manipulation over Entity Framework.

## Build & Test Commands

```bash
# Build entire solution
dotnet build RESTier.slnx

# Run all tests
dotnet test RESTier.slnx

# Run a single test project
dotnet test test/Microsoft.Restier.Tests.Core/Microsoft.Restier.Tests.Core.csproj

# Run a specific test by name
dotnet test --filter "FullyQualifiedName~TestMethodName"

# Build a single project
dotnet build src/Microsoft.Restier.Core/Microsoft.Restier.Core.csproj
```

## Architecture

### Core Pipeline (Chain of Responsibility)

RESTier's central pattern is a **chain of responsibility** pipeline for both queries and submissions. Services implement `IChainedService<TService>` with an `Inner` property, composed via `IChainOfResponsibilityFactory`.

**Query pipeline** (`Microsoft.Restier.Core.Query`):
`IQueryExpressionSourcer` -> `IQueryExpressionAuthorizer` -> `IQueryExpressionExpander` -> `IQueryExpressionProcessor` -> `IQueryExecutor`
Orchestrated by `DefaultQueryHandler`.

**Submit pipeline** (`Microsoft.Restier.Core.Submit`):
`IChangeSetInitializer` -> `IChangeSetItemFilter` -> `IChangeSetItemAuthorizer` -> `IChangeSetItemValidator` -> `ISubmitExecutor`
Orchestrated by `DefaultSubmitHandler`.

### Convention-Based Interception

RESTier discovers interceptor methods by naming convention on `ApiBase` subclasses:
- `OnFiltering{EntitySet}()` / `OnInserting{Entity}()` / `OnValidating{Entity}()` etc.
- Implemented via `ConventionBasedQueryExpressionProcessor`, `ConventionBasedChangeSetItemFilter`, `ConventionBasedChangeSetItemValidator`

### Key Base Classes

- `ApiBase` - Base class for all RESTier APIs; subclass to define your API surface
- `EntityFrameworkApi<TContext>` - EF-specific base providing DbContext integration
- `RestierController : ODataController` - Handles OData HTTP requests in ASP.NET Core

### Project Layout

| Directory | Purpose |
|-----------|---------|
| `src/Microsoft.Restier.Core` | Core abstractions, pipelines, conventions, DI |
| `src/Microsoft.Restier.AspNetCore` | ASP.NET Core integration, routing, controller |
| `src/Microsoft.Restier.EntityFramework` | Entity Framework 6.x support |
| `src/Microsoft.Restier.EntityFrameworkCore` | Entity Framework Core support |
| `src/Microsoft.Restier.EntityFramework.Shared` | Shared EF code (shared project, not NuGet) |
| `src/Microsoft.Restier.Breakdance` | In-memory testing framework |
| `src/Microsoft.Restier.AspNetCore.Swagger` | Swagger/OpenAPI generation |

### Dependency Injection

Uses `Microsoft.Extensions.DependencyInjection` with per-route service containers. Service registration extensions are in `Microsoft.Restier.Core.DependencyInjection` and `Microsoft.Restier.AspNetCore.Extensions`.

## Code Conventions

- **Targets:** .NET 8.0, .NET 9.0, and .NET Framework 4.8
- **Warnings as errors** enabled globally
- **Implicit usings disabled** - all `using` directives must be explicit
- **Nullable reference types disabled**
- **Strong name signing** with `restier.snk`
- **Allman brace style**, prefer `var`, prefer curly braces even for single-line blocks
- **InternalsVisibleTo** is auto-configured from source to matching test project

## Test Conventions

- **Framework:** xUnit v3, FluentAssertions (AwesomeAssertions), NSubstitute
- **Project naming:** `X` -> `X.Tests` (e.g., `Microsoft.Restier.Core` -> `Microsoft.Restier.Tests.Core`)
- **File naming:** `X/Y/Z/A.cs` -> `X.Tests/Y/Z/ATests.cs`
- **Namespace:** must match folder path (e.g., `Microsoft.Restier.Tests.Core.Convention`)
- **Integration/scenario tests** go in `X.Tests/IntegrationTests` or `X.Tests/ScenarioTests`

## Documentation

Documentation lives in `src/Microsoft.Restier.Docs/` and is built with the **DotNetDocs SDK** (`<Project Sdk="DotNetDocs.Sdk/1.2.0">`), which generates Mintlify-flavored MDX.

```bash
# Build the docs project (regenerates api-reference/ and docs.json)
dotnet build src/Microsoft.Restier.Docs/Microsoft.Restier.Docs.docsproj
```

The docs project is part of `RESTier.slnx`, so a full solution build also builds the docs:

```bash
dotnet build RESTier.slnx
```

**Authoring conventions:**
- Hand-written content lives under `guides/`, `release-notes/`, and the project root (`index.mdx`, `quickstart.mdx`, `contribution-guidelines.mdx`, `why-restier.mdx`).
- API reference under `api-reference/` is auto-generated from XML doc comments (six assemblies at TFM `net9.0`) and gitignored — do NOT hand-edit it.
- Pages use Mintlify components: `<Info>`, `<Note>`, `<Tip>`, `<Warning>`, `<Steps>`, `<CodeGroup>`, `<Tabs>`, `<CardGroup>`. See existing pages for examples.

**Navigation source of truth:** the `<MintlifyTemplate>` block in `Microsoft.Restier.Docs.docsproj`. The SDK regenerates `docs.json` from this template on every build, so commit `docs.json` alongside any nav-affecting change but do not hand-edit it.

**Build-ordering note:** the docsproj has an explicit `BuildSourceProjectsForDocs` target that calls `<MSBuild>` on each documented source project for `net8.0` before doc generation runs. The DotNetDocs SDK resolves assembly paths against `bin/Debug/net8.0/`, and `<ProjectReference>` items alone don't reliably trigger a full Build of the multi-targeted source projects from this NoTargets-style docsproj.

`assembly-list.txt` under the docs project is a Debug-build debug dump written by the SDK (not configuration). It is gitignored.

## Key Dependencies

- Microsoft.OData.Core / Microsoft.OData.Edm (8.x)
- Microsoft.OData.ModelBuilder (2.x)
- Microsoft.AspNetCore.OData (9.x)
- EntityFramework 6.5.x / EntityFrameworkCore 8.x-10.x
55 changes: 34 additions & 21 deletions src/Directory.Build.props → Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
<PropertyGroup>
<IsBenchmarkProject Condition="$(MSBuildProjectName.EndsWith('.Performance'))">true</IsBenchmarkProject>
<IsTestProject Condition="$(MSBuildProjectName.ToLower().Contains('.tests.'))">true</IsTestProject>
<IsTestSharedProject Condition="$(MSBuildProjectName.ToLower().Contains('.tests.shared'))">true</IsTestSharedProject>
<IsTestAssetProject Condition="$(RepoRelativeProjectDir.ToLower().Contains('testassets'))">true</IsTestAssetProject>
<IsSampleProject Condition="$(MSBuildProjectName.ToLower().Contains('.samples.'))">true</IsSampleProject>
<IsTemplateProject Condition="$(MSBuildProjectName.ToLower().Contains('.templates.'))">true</IsTemplateProject>
Expand Down Expand Up @@ -81,19 +82,13 @@
<!-- Suppress warnings about pre-release packages -->
<NoWarn>$(NoWarn);NU5104</NoWarn>

</PropertyGroup>
<!-- Suppress .NET 10 package pruning warnings for multi-targeted packages that are in-box on net10.0 -->
<NoWarn>$(NoWarn);NU1510</NoWarn>

<!-- Base settings for all test projects -->
<PropertyGroup Condition=" $(IsTestProject) == 'true' ">
<NoWarn>$(NoWarn);CA1001;CA1031;CA1062;CA1301;CA1303;AC1307;CA1707;CA1716;CA1801;CA1806;CA1819;CA1822;CA1825;CA2000;CA2007;CA2227;CA2234</NoWarn>
<IsPackable>false</IsPackable>
</PropertyGroup>

<!-- Use VSTest for all test projects to support both net48 and modern .NET in the same test run.
MSTest 4.x with EnableMSTestRunner=true would enable Microsoft.Testing.Platform,
but that conflicts with net48 projects which cannot use MTP. -->
<PropertyGroup Condition=" $(IsTestProject) == 'true' ">
<EnableMSTestRunner>false</EnableMSTestRunner>
<NoWarn>$(NoWarn);CA1001;CA1031;CA1062;CA1301;CA1303;AC1307;CA1707;CA1716;CA1801;CA1806;CA1819;CA1822;CA1825;CA2000;CA2007;CA2227;CA2234</NoWarn>
</PropertyGroup>

<PropertyGroup Condition=" $(IsSampleProject) == 'true' ">
Expand All @@ -108,26 +103,44 @@

<PropertyGroup>
<StandardTestTfms>net48</StandardTestTfms>
<RestierBreakdanceVersion>[8.0.0, 9.0.0)</RestierBreakdanceVersion>
<RestierEasyAfVersion>[4.0.0, 5.0.0)</RestierEasyAfVersion>
<RestierNet9DependencyInjectionVersion>[9.*, 10.0.0)</RestierNet9DependencyInjectionVersion>
<RestierNet9EntityFrameworkVersion>[9.*, 10.0.0)</RestierNet9EntityFrameworkVersion>
<RestierNet9SystemTextJsonVersion>[9.*, 10.0.0)</RestierNet9SystemTextJsonVersion>
<RestierNet9UserSecretsVersion>[9.*, 10.0.0)</RestierNet9UserSecretsVersion>
<RestierNet9AspNetCoreTestHostVersion>[9.*, 10.0.0)</RestierNet9AspNetCoreTestHostVersion>
<RestierNet10DependencyInjectionVersion>[10.*, 11.0.0)</RestierNet10DependencyInjectionVersion>
<RestierNet10EntityFrameworkVersion>[10.*, 11.0.0)</RestierNet10EntityFrameworkVersion>
<RestierNet10SystemTextJsonVersion>[10.*, 11.0.0)</RestierNet10SystemTextJsonVersion>
<RestierNet10UserSecretsVersion>[10.*, 11.0.0)</RestierNet10UserSecretsVersion>
<RestierNet10AspNetCoreTestHostVersion>[10.*, 11.0.0)</RestierNet10AspNetCoreTestHostVersion>
</PropertyGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net9.0'">
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="$(RestierNet9DependencyInjectionVersion)" PrivateAssets="All" />
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="$(RestierNet9UserSecretsVersion)" PrivateAssets="All" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="$(RestierNet9UserSecretsVersion)" PrivateAssets="All" />
<PackageReference Include="Microsoft.Extensions.FileProviders.Abstractions" Version="$(RestierNet9UserSecretsVersion)" PrivateAssets="All" />
<PackageReference Include="Microsoft.Extensions.FileProviders.Physical" Version="$(RestierNet9UserSecretsVersion)" PrivateAssets="All" />
<PackageReference Include="System.Text.Json" Version="$(RestierNet9SystemTextJsonVersion)" PrivateAssets="All" />
</ItemGroup>


<ItemGroup Condition=" $(IsTestProject) != 'true' AND $(IsSampleProject) != 'true'">
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="8.*" PrivateAssets="All" />

<InternalsVisibleTo Include="$(AssemblyName.Replace('Microsoft.Restier.', 'Microsoft.Restier.Tests.')), $(StrongNamePublicKey)" />
</ItemGroup>

<ItemGroup Condition=" $(IsTestProject) == 'true' and $(IsSampleProject) != 'true'">
<ItemGroup Condition=" $(IsTestProject) == 'true' and $(IsSampleProject) != 'true' and $(IsTestSharedProject) != 'true'">
<PackageReference Include="coverlet.collector" Version="6.*" />
<PackageReference Include="FluentAssertions" Version="6.*" PrivateAssets="All" />
<PackageReference Include="FluentAssertions.Analyzers" Version="0.*" PrivateAssets="All" />
<PackageReference Include="MSTest" Version="4.*" />

<!-- Enable parallel test execution in MSTest 4 and later. -->
<AssemblyAttribute Include="Microsoft.VisualStudio.TestTools.UnitTesting.Parallelize">
<_Parameter1>Workers = 1</_Parameter1>
<_Parameter1_IsLiteral>true</_Parameter1_IsLiteral>
<_Parameter2>Scope = Microsoft.VisualStudio.TestTools.UnitTesting.ExecutionScope.MethodLevel</_Parameter2>
<_Parameter2_IsLiteral>true</_Parameter2_IsLiteral>
</AssemblyAttribute>
<PackageReference Include="AwesomeAssertions" Version="8.*" PrivateAssets="All" />
<PackageReference Include="AwesomeAssertions.Analyzers" Version="0.*" PrivateAssets="All" />
<PackageReference Include="xunit.v3" Version="3.*" />
<PackageReference Include="xunit.runner.visualstudio" Version="3.*" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.*" />
<PackageReference Include="NSubstitute" Version="5.3.0"></PackageReference>
</ItemGroup>

<ItemGroup>
Expand Down
52 changes: 52 additions & 0 deletions RESTier.slnx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<Solution>
<Folder Name="/Solution Items/">
<File Path="NuGet.Config" />
<File Path="README.md" />
<File Path=".editorconfig" />
<File Path="Directory.Build.props" />
<File Path="dotnet-logo.png" />
</Folder>
<Folder Name="/src/" Id="02ea681e-c7d8-13c7-8484-4ac65e1b71e8">
<Project Path="src/Microsoft.Restier.Breakdance/Microsoft.Restier.Breakdance.csproj" />
<Project Path="src/Microsoft.Restier.Core/Microsoft.Restier.Core.csproj" />
<Project Path="src/Microsoft.Restier.EntityFramework.Spatial/Microsoft.Restier.EntityFramework.Spatial.csproj" />
<Project Path="src/Microsoft.Restier.EntityFrameworkCore.Spatial/Microsoft.Restier.EntityFrameworkCore.Spatial.csproj" />
</Folder>
<Folder Name="/src/EntityFramework/" Id="a290b16b-6f9e-4703-8c01-135831ad90df">
<Project Path="src/Microsoft.Restier.EntityFramework.Shared/Microsoft.Restier.EntityFramework.Shared.shproj" Id="83ad7aa8-9ed8-4b9f-966a-73ce9cae51c6" />
<Project Path="src/Microsoft.Restier.EntityFramework/Microsoft.Restier.EntityFramework.csproj" />
<Project Path="src/Microsoft.Restier.EntityFrameworkCore/Microsoft.Restier.EntityFrameworkCore.csproj" />
</Folder>
<Folder Name="/src/Samples/">
<Project Path="src/Microsoft.Restier.Samples.Northwind.AspNetCore/Microsoft.Restier.Samples.Northwind.AspNetCore.csproj" />
<Project Path="src/Microsoft.Restier.Samples.NorthwindVersioned.AspNetCore/Microsoft.Restier.Samples.NorthwindVersioned.AspNetCore.csproj" />
<Project Path="src/Microsoft.Restier.Samples.Postgres.AspNetCore/Microsoft.Restier.Samples.Postgres.AspNetCore.csproj" />
</Folder>
<Folder Name="/src/Web/" Id="bf61c3f1-7c7e-4515-8b51-14b374a034f9">
<Project Path="src/Microsoft.Restier.AspNetCore.NSwag/Microsoft.Restier.AspNetCore.NSwag.csproj" />
<Project Path="src/Microsoft.Restier.AspNetCore.Swagger/Microsoft.Restier.AspNetCore.Swagger.csproj" />
<Project Path="src/Microsoft.Restier.AspNetCore.Versioning/Microsoft.Restier.AspNetCore.Versioning.csproj" />
<Project Path="src/Microsoft.Restier.AspNetCore/Microsoft.Restier.AspNetCore.csproj" />
</Folder>
<Folder Name="/docs/">
<Project Path="src/Microsoft.Restier.Docs/Microsoft.Restier.Docs.docsproj" Type="C#" />
</Folder>
<Folder Name="/test/" Id="67e76b39-b345-4061-b1a8-31b95b6f83a8">
<Project Path="test/Microsoft.Restier.Tests.Core/Microsoft.Restier.Tests.Core.csproj" />
<Project Path="test/Microsoft.Restier.Tests.EntityFramework.Spatial/Microsoft.Restier.Tests.EntityFramework.Spatial.csproj" />
<Project Path="test/Microsoft.Restier.Tests.Shared/Microsoft.Restier.Tests.Shared.csproj" />
</Folder>
<Folder Name="/test/EntityFramework/" Id="b45d57df-5e57-4cf8-9ff8-86a03f39bb09">
<Project Path="test/Microsoft.Restier.Tests.EntityFramework/Microsoft.Restier.Tests.EntityFramework.csproj" />
<Project Path="test/Microsoft.Restier.Tests.EntityFrameworkCore.Spatial/Microsoft.Restier.Tests.EntityFrameworkCore.Spatial.csproj" />
<Project Path="test/Microsoft.Restier.Tests.EntityFrameworkCore/Microsoft.Restier.Tests.EntityFrameworkCore.csproj" />
<Project Path="test/Microsoft.Restier.Tests.Shared.EntityFramework/Microsoft.Restier.Tests.Shared.EntityFramework.csproj" />
<Project Path="test/Microsoft.Restier.Tests.Shared.EntityFrameworkCore/Microsoft.Restier.Tests.Shared.EntityFrameworkCore.csproj" />
</Folder>
<Folder Name="/test/Web/" Id="ae160b58-fb2d-4b9f-9357-8c7648381b95">
<Project Path="test/Microsoft.Restier.Tests.AspNetCore.NSwag/Microsoft.Restier.Tests.AspNetCore.NSwag.csproj" />
<Project Path="test/Microsoft.Restier.Tests.AspNetCore.Swagger/Microsoft.Restier.Tests.AspNetCore.Swagger.csproj" />
<Project Path="test/Microsoft.Restier.Tests.AspNetCore.Versioning/Microsoft.Restier.Tests.AspNetCore.Versioning.csproj" />
<Project Path="test/Microsoft.Restier.Tests.AspNetCore/Microsoft.Restier.Tests.AspNetCore.csproj" />
</Folder>
</Solution>
Binary file added docs/.DS_Store
Binary file not shown.
8 changes: 0 additions & 8 deletions docs/CODEOWNERS

This file was deleted.

13 changes: 0 additions & 13 deletions docs/README.md

This file was deleted.

31 changes: 0 additions & 31 deletions docs/mkdocs.yml

This file was deleted.

1 change: 0 additions & 1 deletion docs/msdocs/clients/dot-net-standard.md

This file was deleted.

1 change: 0 additions & 1 deletion docs/msdocs/clients/dot-net.md

This file was deleted.

1 change: 0 additions & 1 deletion docs/msdocs/clients/typescript.md

This file was deleted.

Loading
Loading