Skip to content

Commit e6dbbe8

Browse files
Merge pull request #10 from MelbourneDeveloper/sync
Summary This release transforms DataProvider from a SQL code generator into a comprehensive data layer suite. It adds three major new components: Sync Framework - Offline-first bidirectional synchronization engine Gatekeeper - Passwordless authentication and fine-grained authorization microservice Healthcare Samples - FHIR-compliant clinical and scheduling APIs with React dashboard Statistics 373 files changed ~130,000 lines added ~1,600 lines removed (cleanup of obsolete specs) New Components Sync Framework (Sync/) A database-agnostic, offline-first synchronization framework for .NET applications. Features: Two-way synchronization with version-based change tracking Conflict resolution strategies (last-write-wins, server-wins, custom) Foreign key handling with automatic deferred retry Tombstone management for safe deletion tracking Real-time subscriptions via Server-Sent Events (SSE) SHA-256 hash verification for data integrity Mapping engine for heterogeneous schema sync between microservices Database support: SQLite and PostgreSQL Projects: Project Lines Description Sync.Core ~3,500 Core sync engine, coordinator, conflict resolver Sync.SQLite ~2,500 SQLite triggers, schema, repositories Sync.Postgres ~1,200 PostgreSQL implementation Sync.Http ~800 REST endpoints with SSE Sync.Tests ~5,000 Core unit tests Sync.SQLite.Tests ~4,500 SQLite integration tests Sync.Postgres.Tests ~1,500 PostgreSQL integration tests Sync.Http.Tests ~3,500 API endpoint tests Sync.Integration.Tests ~1,200 Cross-database E2E tests Gatekeeper (Gatekeeper/) An independent authentication and authorization microservice. Features: Passwordless authentication with WebAuthn/FIDO2 passkeys Role-based access control (RBAC) with hierarchical roles Record-level permissions for fine-grained access JWT session management with revocation Framework-agnostic REST API Projects: Project Lines Description Gatekeeper.Api ~1,200 REST API with auth endpoints Gatekeeper.Migration ~250 Database schema Gatekeeper.Api.Tests ~1,400 Integration tests Healthcare Samples (Samples/) A complete demonstration of the DataProvider suite with FHIR-compliant healthcare APIs. Architecture: Dashboard.Web (React/H5) │ ├──► Clinical.Api ◄──── Clinical.Sync ◄─┐ │ (SQLite) │ │ Patient, Encounter, Condition │ Practitioner→Provider │ │ └──► Scheduling.Api ◄── Scheduling.Sync ◄┘ (SQLite) Patient→ScheduledPatient Practitioner, Appointment Projects: Project Description Clinical.Api FHIR Patient, Encounter, Condition, MedicationRequest Clinical.Sync Pulls Practitioner data from Scheduling Scheduling.Api FHIR Practitioner, Appointment, Schedule, Slot Scheduling.Sync Pulls Patient data from Clinical Dashboard.Web React 18 UI transpiled from C# via H5 Dashboard.Integration.Tests Playwright E2E tests Changes to Existing Components DataProvider Core Enhanced DbConnectionExtensions and DbTransactionExtensions Improved code generation for table operations Better nullable handling in generated code Additional tests for edge cases LQL Minor fixes to browser playground Improved file operation handling Documentation Updated root README with complete suite overview New architecture diagrams showing component integration Updated CLAUDE.md with all components and coding rules Individual README files for Sync, Gatekeeper, and Samples Breaking Changes None. This release adds new components without modifying existing APIs. Testing All components include comprehensive test suites following the project's testing philosophy: E2E integration tests with real databases (no mocks) Cross-database tests for Sync (SQLite ↔ PostgreSQL) Playwright tests for Dashboard UI Run all tests: dotnet test Run specific component: dotnet test --filter "FullyQualifiedName~Sync" dotnet test --filter "FullyQualifiedName~Gatekeeper" dotnet test --filter "FullyQualifiedName~Samples" Dependencies New package dependencies: Fido2.AspNet - WebAuthn/FIDO2 implementation for Gatekeeper Npgsql - PostgreSQL driver for Sync.Postgres H5 - C# to JavaScript transpiler for Dashboard Documentation Sync Framework README Sync Specification Gatekeeper README Gatekeeper Specification Samples README Checklist All tests pass Code formatted with dotnet csharpier . Documentation updated No breaking changes to existing APIs Follows coding rules (no exceptions, no classes, Result types)
2 parents 2c917dc + 5eba851 commit e6dbbe8

376 files changed

Lines changed: 130423 additions & 1626 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.config/dotnet-tools.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"version": 1,
3+
"isRoot": true,
4+
"tools": {
5+
"ilspycmd": {
6+
"version": "9.1.0.7988",
7+
"commands": [
8+
"ilspycmd"
9+
],
10+
"rollForward": false
11+
}
12+
}
13+
}

.cursor/rules/CsharpRules.mdc

Lines changed: 0 additions & 28 deletions
This file was deleted.

.editorconfig

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,11 @@ csharp_style_expression_bodied_methods = true
55

66
# CA1062: Validate arguments of public methods - DISABLED because we use nullable reference types
77
dotnet_diagnostic.CA1062.severity = none
8+
9+
# IDE0037: Member name can be simplified - DISABLED for anonymous objects
10+
dotnet_diagnostic.IDE0037.severity = none
11+
12+
# CA1308: Normalize strings to uppercase - DISABLED because lowercase is intentional for identifiers and hashes
13+
dotnet_diagnostic.CA1308.severity = none
14+
15+

.gitignore

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,13 @@ invoices.db
404404
*.bak
405405
*.swp
406406
*~
407-
coverage_report/
408407

409-
final_coverage_report/
408+
coverage/
409+
coverage-report/
410+
coverage-results/
411+
412+
413+
414+
Samples/Dashboard/Dashboard.Web/wwwroot/js/vendor/
415+
416+
*.db

.vscode/launch.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,20 @@
11
{
22
"version": "0.2.0",
33
"configurations": [
4+
{
5+
"name": "Dashboard (Fresh)",
6+
"type": "node-terminal",
7+
"request": "launch",
8+
"command": "${workspaceFolder}/Samples/start.sh --fresh",
9+
"cwd": "${workspaceFolder}/Samples"
10+
},
11+
{
12+
"name": "Dashboard (Continue)",
13+
"type": "node-terminal",
14+
"request": "launch",
15+
"command": "${workspaceFolder}/Samples/start.sh",
16+
"cwd": "${workspaceFolder}/Samples"
17+
},
418
{
519
"name": "Launch Blazor LQL Website",
620
"type": "coreclr",

.vscode/settings.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
{
22
"csharp.maxProjectFileCountForDiagnosticAnalysis": 10000,
33
"dotnet.backgroundAnalysis.analyzerDiagnosticsScope": "fullSolution",
4-
"dotnet.backgroundAnalysis.compilerDiagnosticsScope": "fullSolution"
4+
"dotnet.backgroundAnalysis.compilerDiagnosticsScope": "fullSolution",
5+
"code-runner.clearPreviousOutput": true,
6+
"code-runner.saveFileBeforeRun": true,
7+
"code-runner.runInTerminal": true
58
}

.windsurf/rules/CsharpRules.md

Lines changed: 0 additions & 28 deletions
This file was deleted.

Agents.md

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Multi-Agent Coordination (Too Many Cooks)
6+
- Keep your key! It's critical. Do not lose it!
7+
- Check messages regularly, lock files before editing, unlock after
8+
- Don't edit locked files; signal intent via plans and messages
9+
- Coordinator: keep delegating via messages. Worker: keep asking for tasks via messages
10+
- Clean up expired locks routinely
11+
- Do not use Git unless asked by user
12+
13+
Medical: All medical data MUST conform to the [FHIR spec](https://build.fhir.org/resourcelist.html).
14+
15+
## Build Commands
16+
```bash
17+
dotnet build DataProvider.sln # Build entire solution
18+
dotnet test # Run all tests
19+
dotnet test --filter "FullyQualifiedName~ClassName" # Run specific test class
20+
dotnet test --filter "FullyQualifiedName~MethodName" # Run single test
21+
dotnet csharpier . # Format all code (run periodically)
22+
```
23+
24+
DO NOT USE GIT!!! <-- ⛔️ Source control is illegal for you 🙅🏼
25+
26+
## Architecture Overview
27+
28+
This repository contains two complementary projects:
29+
30+
**DataProvider** - Source generator creating compile-time safe extension methods from SQL files
31+
- Core library in `DataProvider/DataProvider/` - base types, config records, code generation
32+
- Database-specific implementations: `DataProvider.SQLite/`, `DataProvider.SqlServer/`
33+
- Uses ANTLR grammars for SQL parsing (`Parsing/*.g4` files)
34+
- Generates extension methods on `IDbConnection` and `IDbTransaction`
35+
- Routinely format all C# code with `dotnet csharpier .`
36+
37+
**LQL (Lambda Query Language)** - Functional DSL that transpiles to SQL
38+
- Core transpiler in `Lql/Lql/` - ANTLR grammar, pipeline steps, AST
39+
- Database dialects: `Lql.SQLite/`, `Lql.SqlServer/`, `Lql.Postgres/`
40+
- CLI tool: `LqlCli.SQLite/`
41+
- Browser playground: `Lql.Browser/`
42+
43+
**Shared Libraries** in `Other/`:
44+
- `Results/` - `Result<TValue, TError>` type for functional error handling
45+
- `Selecta/` - SQL parsing and AST utilities
46+
47+
## Coding Rules (CRITICAL)
48+
49+
- **NEVER THROW EXCEPTIONS** - Always return `Result<T>` for fallible operations. Wrap anything that can fail in try/catch
50+
- **NO CLASSES** - Use records and static methods. FP style with pure static methods
51+
- **Copious logging with ILogger** - Especially in the sync projects
52+
- **NO INTERFACES** - Use `Action<T>` or `Func<T>` for abstractions
53+
- **AVOID ASSIGNMENTS** - Use expressions where possible
54+
- **Static extension methods on IDbConnection and IDbTransaction only** - No classes for data access
55+
- **Test at the highest level** - Avoid mocks. Only full integration testing
56+
- **Always use type aliases (using) for result types** - Don't write like this: `new Result<string, SqlError>.Ok`
57+
- **No singletons** - Inject `Func` into static methods
58+
- **Immutable types!** - Use records. Don't use `List<T>`. Use `ImmutableList` `FrozenSet` or `ImmutableArray`
59+
- **NO REGEX** - Parse SQL with ANTLR .g4 grammars or SqlParserCS library
60+
- **All public members require XMLDOC** - Except in test projects
61+
- **Keep files under 450 LOC**
62+
- **One type per file** (except small records)
63+
- **No commented-out code** - Delete it
64+
- **No consecutive Console.WriteLine** - Use single string interpolation
65+
- **No placeholders** - If incomplete, leave LOUD compilation error with TODO
66+
- **Never use Fluent Assertions**
67+
68+
## Project Configuration
69+
70+
- .NET 9.0, C# latest with nullable enabled
71+
- All warnings as errors (TreatWarningsAsErrors=true)
72+
- Central config in `Directory.Build.props` - don't duplicate in .csproj files
73+
- xUnit for testing with Moq
74+
75+
## Code Generation Note
76+
77+
This is a code generation project. Don't generate code manually that is the responsibility of the generator. Check for existing types/methods before creating new ones.

CLAUDE.md

Lines changed: 112 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,112 @@
1-
- NEVER THROW EXCEPTIONS!!!!!! Always return a result type for methods that could fail. Anything that can fail is wrapped in a try/catch
2-
- You are building a code generation. Don't generate code yourself that is the responsibility of the generator
3-
- AVOID DUPLICATION. Always check for the existence of types, methods and variables before creating them
4-
- No interfaces! Use Action<T> or Func<T> for abstractions
5-
- AVOID ASSIGNMENTS!!!! Use EXPRESSIONS where possible
6-
- NO CONSECUTIVE Console.WriteLine calls. Use string interpolation on a sinle line
7-
- DO NOT USE GIT - Unless explicitly requested
8-
- Static extension methods on IDbConnection and ITransaction only! No classes for getting data
9-
- No singletons! Inject Func into static methods
10-
- NO CLASSES. Records and Static Methods!!! - FP style code wherever with pure static methods
11-
- Turn all warnings up to ERRORS and include as many Roslyn analyzer rules as possible, especially for null safety
12-
- Keep files under 450 LOC
13-
- Run dotnet csharpier . on the root folder of the repo every now and then
14-
- No placeholders! If you don't have time to implement something properly, leave a LOUD compilation error with a TODO instead
15-
- All public members MUST have XMLDOC documentation, except on tests
16-
- DON'T use Regex! Parse the SQL with the official Antlr .g4 or a well tested existing parsing library
17-
- Use a build props for everything and remove duplicate config from the csproj, especially Roslyn/code rule config.
18-
- Keep the readme updated
19-
- Don't put temp files or anything in the root folder
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
# Rules
6+
7+
## Multi-Agent Coordination (Too Many Cooks)
8+
- Keep your key! It's critical. Do not lose it!
9+
- Check messages regularly, lock files before editing, unlock after
10+
- Don't edit locked files; signal intent via plans and messages
11+
- Coordinator: keep delegating via messages. Worker: keep asking for tasks via messages
12+
- Telegraph EVERYTHING with messages and plan updates
13+
- Clean up expired locks routinely
14+
15+
## Coding Rules
16+
17+
- **NEVER THROW EXCEPTIONS** - Always return `Result<T>` for fallible operations. Wrap anything that can fail in try/catch
18+
- **No casting or using ! for nulls** - Only pattern matching on type
19+
- **DO NOT USE GIT** <-- ⛔️ Source control is illegal for you 🙅🏼
20+
- **Do not supress analyzer warnings/errors** <-- Illegal
21+
- **No direct CREATE TABLE or other SQL to create schema** - Use the DataProvider Migrations!
22+
- **No direct SQL inserts/Updates!** - Generate extensions for inserts/updates with DataProvider
23+
- **NO CLASSES** - Use records and static methods. FP style with pure static methods
24+
- **Copious logging with ILogger** - Especially in the sync projects
25+
- **NO INTERFACES** - Use `Action<T>` or `Func<T>` for abstractions
26+
- **AVOID ASSIGNMENTS** - Use expressions where possible
27+
- **You MUST close type hierarchies** - Make the constructor restricted so it is not possible to create new implementations from the base type. Eg:
28+
```csharp
29+
public abstract partial record Result<TSuccess, TFailure>
30+
{
31+
// [...]
32+
/// </summary>
33+
private Result() { }
34+
// [...]
35+
}
36+
``
37+
- **Static extension methods on IDbConnection and IDbTransaction only** - No classes for data access
38+
- **Don't use statements like if** - use pattern matching switch expressions on type
39+
⛔️ wrong
40+
```csharp
41+
if (triggerResult is Result<bool, SyncError>.Error<bool, SyncError> triggerErr)
42+
```
43+
- **Skipping tests = ⛔️ ILLEGAL** - Failing tests = OK. Aggressively unskip tests
44+
- **Test at the highest level** - Avoid mocks. Only full integration testing
45+
- **Always use type aliases (using) for result types** - Don't write like this: `new Result<string, SqlError>.Ok`
46+
- **No singletons** - Inject `Func` into static methods
47+
- **Immutable types!** - Use records. Don't use `List<T>`. Use `ImmutableList` `FrozenSet` or `ImmutableArray`
48+
- **NO REGEX** - Parse SQL with ANTLR .g4 grammars or SqlParserCS library
49+
- **All public members require XMLDOC** - Except in test projects
50+
- **Keep files under 450 LOC**
51+
- **One type per file** (except small records)
52+
- **No commented-out code** - Delete it
53+
- **No consecutive Console.WriteLine** - Use single string interpolation
54+
- **No placeholders** - If incomplete, leave LOUD compilation error with TODO
55+
- **Never use Fluent Assertions**
56+
57+
## Testing
58+
- Use e2e tests with zero mocking where possible
59+
- Fall back on unit testing only when absolutely necessary
60+
- Create MEANINGFUL tests that test REAL WORLD use cases
61+
- All projects must have 100% test coverage and a Stryker Mutator testing score of 70% or above. Use [Stryker Mutator](https://stryker-mutator.io/docs/stryker-net/getting-started/) as the ultimate arbiter of test quality
62+
63+
## Architecture Overview
64+
65+
This repository contains four major components:
66+
67+
**DataProvider** - Source generator creating compile-time safe extension methods from SQL files
68+
- Core library in `DataProvider/DataProvider/` - base types, config records, code generation
69+
- Database-specific implementations: `DataProvider.SQLite/`, `DataProvider.SqlServer/`
70+
- Uses ANTLR grammars for SQL parsing (`Parsing/*.g4` files)
71+
- Generates extension methods on `IDbConnection` and `IDbTransaction`
72+
- Routinely format all C# code with `dotnet csharpier .`
73+
74+
**LQL (Lambda Query Language)** - Functional DSL that transpiles to SQL
75+
- Core transpiler in `Lql/Lql/` - ANTLR grammar, pipeline steps, AST
76+
- Database dialects: `Lql.SQLite/`, `Lql.SqlServer/`, `Lql.Postgres/`
77+
- CLI tool: `LqlCli.SQLite/`
78+
- Browser playground: `Lql.Browser/`
79+
80+
**Sync Framework** - Offline-first bidirectional synchronization
81+
- Core engine in `Sync/Sync/` - SyncCoordinator, ConflictResolver, BatchManager
82+
- Database implementations: `Sync.SQLite/`, `Sync.Postgres/`
83+
- HTTP layer: `Sync.Http/` - REST endpoints with SSE subscriptions
84+
- Key components: TriggerGenerator, ChangeApplier, MappingEngine
85+
- Comprehensive tests: `Sync.Tests/`, `Sync.SQLite.Tests/`, `Sync.Postgres.Tests/`
86+
87+
**Gatekeeper** - Authentication and authorization microservice
88+
- API in `Gatekeeper/Gatekeeper.Api/` - WebAuthn passkey auth, RBAC, record-level permissions
89+
- Schema in `Gatekeeper/Gatekeeper.Migration/` - Uses DataProvider migrations
90+
- Key files: `TokenService.cs`, `AuthorizationService.cs`, `Program.cs`
91+
- Tests: `Gatekeeper/Gatekeeper.Api.Tests/`
92+
93+
**Shared Libraries** in `Other/`:
94+
- `Results/` - `Result<TValue, TError>` type for functional error handling
95+
- `Selecta/` - SQL parsing and AST utilities
96+
97+
**Samples** - Healthcare microservices demonstrating the suite
98+
- `Samples/Clinical/` - FHIR-compliant clinical API (Patient, Encounter, Condition)
99+
- `Samples/Scheduling/` - FHIR-compliant scheduling API (Practitioner, Appointment)
100+
- `Samples/Dashboard/` - React/H5 dashboard
101+
- Medical: All medical data MUST conform to the [FHIR spec](https://build.fhir.org/resourcelist.html).
102+
103+
## Project Configuration
104+
105+
- .NET 9.0, C# latest with nullable enabled
106+
- All warnings as errors (TreatWarningsAsErrors=true)
107+
- Central config in `Directory.Build.props` - don't duplicate in .csproj files
108+
- xUnit for testing with Moq
109+
110+
## Code Generation Note
111+
112+
This is a code generation project. Don't generate code manually that is the responsibility of the generator. Check for existing types/methods before creating new ones.

CodeAnalysis.ruleset

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
<Rule Id="CA1002" Action="None" />
1313
<Rule Id="CA1062" Action="None" />
1414
<Rule Id="CA1002" Action="None" />
15+
<!-- Mark assemblies with assembly version -->
16+
<Rule Id="CA1017" Action="None" />
17+
<Rule Id="IDE0037" Action="Error" />
1518
<Rule Id="IDE0301" Action="Error" />
1619
<Rule Id="IDE0042" Action="Error" />
1720
<Rule Id="IDE0056" Action="Error" />
@@ -48,8 +51,6 @@
4851
<Rule Id="CA1010" Action="Error" />
4952
<!-- Generic interface should also be implemented -->
5053
<Rule Id="CA1012" Action="Error" />
51-
<!-- Mark assemblies with assembly version -->
52-
<Rule Id="CA1017" Action="Error" />
5354
<!-- Mark assemblies with ComVisible -->
5455
<Rule Id="CA1018" Action="Error" />
5556
<!-- Mark attributes with AttributeUsageAttribute -->

0 commit comments

Comments
 (0)