You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: .claude/skills/csharp-sync/SKILL.md
+78-7Lines changed: 78 additions & 7 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,18 +1,34 @@
1
1
---
2
2
name: csharp-sync
3
3
description: Migrates RavenDB C# client features to the Python client. Use when porting C# diffs, patches, or test files to Python, batching sync work, or writing migration tests.
If arguments were provided (`$ARGUMENTS`), use them as the starting point:
23
+
- If it's a file path, read it as the diff/patch input
24
+
- If it's a feature name, fetch the relevant C# source to begin triage
25
+
11
26
## Pipeline
12
27
13
28
1.**Triage** — read the diff, list every changed file, group into batches
14
-
2.**Implement** — port each batch following [CONVENTIONS.md](CONVENTIONS.md)
15
-
3.**Test** — migrate or write tests following [TESTING.md](TESTING.md)
29
+
2.**Plan** — present the batch plan to the user and wait for approval before writing any code
30
+
3.**Implement** — port each batch following [CONVENTIONS.md](CONVENTIONS.md)
31
+
4.**Test** — migrate or write tests following [TESTING.md](TESTING.md)
16
32
17
33
## Reference sources
18
34
@@ -67,31 +83,82 @@ Use docs to determine whether a C# change is:
67
83
2. For unfamiliar changes, **fetch the full C# source** from GitHub to understand context.
68
84
3.**Check RavenDB docs** to confirm the feature is documented and understand its scope.
69
85
4.**Filter out** changes that are C#-specific or relate to features not yet in the Python client.
70
-
5. Group remaining changes into **batches** by feature area. Good boundaries:
86
+
5.**Search for existing Python equivalents** — for each changed C# file, Grep for the class name, operation name, or endpoint path in the Python codebase:
87
+
- If a Python version exists, compare it with the C# version to identify only the delta to port.
88
+
- If the Python version has intentional divergences (different architecture, Pythonic patterns), preserve them.
89
+
6. Group remaining changes into **batches** by feature area. Good boundaries:
71
90
- New operation class (e.g. `ConfigureRemoteAttachmentsOperation`)
72
91
- New model / DTO cluster (e.g. settings + configuration classes)
73
92
- New exception type + dispatcher wiring
74
93
- Test migration for an already-implemented feature
75
-
6. Create a **checklist** — one `- [ ]` per batch, ordered by dependency (models → operations → tests).
94
+
7. Create a **checklist** — one `- [ ]` per batch, ordered by dependency (models → operations → tests).
95
+
Use TodoWrite to create tasks for each batch. Mark each as completed before moving to the next.
76
96
77
97
### Batch sizing
78
98
79
99
- Target **≤ 300 lines of Python** per batch.
80
100
- If a single C# file maps to > 300 lines, split by class or logical section.
81
101
- Tests are their own batch, listed after the implementation batch they cover.
102
+
- If a batch modifies existing models/DTOs that have downstream consumers, include the consumer updates in the same batch — even if it exceeds the 300-line target. A broken intermediate state is worse than a large batch.
103
+
104
+
## Step 2 — Present the plan for approval
105
+
106
+
Before writing any code, present the full migration plan to the user. The plan should include:
82
107
83
-
## Step 2 — Implement each batch
108
+
1.**Summary** — what the diff covers and what will be ported vs. skipped.
109
+
2.**Batch list** — numbered batches with:
110
+
- Batch name / feature area
111
+
- Which C# files map to which Python files (new or existing)
112
+
- Estimated scope (new file, modify existing, add fields, etc.)
113
+
- Any risks or ambiguities flagged during triage
114
+
3.**Skipped items** — C# changes filtered out and why (C#-specific, dependency not ported, etc.)
115
+
4.**Open questions** — anything that needs the user's decision before implementation.
116
+
117
+
**Wait for the user to approve the plan before proceeding to Step 3.** The user may reorder batches, split/merge them, or ask to skip certain items. Adjust the TodoWrite tasks accordingly.
118
+
119
+
## Step 3 — Implement each batch
120
+
121
+
Only proceed after user approval from Step 2.
84
122
85
123
Follow the naming rules and patterns in [CONVENTIONS.md](CONVENTIONS.md).
86
124
125
+
### Porting principle
126
+
127
+
Port the *behavior*, not the *syntax*. If the Python client already handles something in a Pythonic way (context managers, generators, keyword arguments), preserve that pattern even if the C# implementation looks different. The goal is feature parity, not code parity.
128
+
87
129
When porting a C# class, **always fetch the full source from GitHub** — diffs alone often lack constructor signatures, base classes, or `ToJson`/`FromJson` methods needed for a correct port.
88
130
89
131
For every edit:
90
-
1. Use `codebase-retrieval` to find ALL downstream callers, implementations, and tests.
132
+
1. Use Grep and Glob to find ALL downstream callers, implementations, and tests.
91
133
2. Update every affected file — missing a downstream change is a critical failure.
92
134
3. After editing, verify imports resolve and no existing tests are broken.
93
135
4. If unsure about a field or method, check the **RavenDB docs** for the canonical behavior.
94
136
137
+
### When unsure
138
+
139
+
1. If the C# pattern has no direct Python equivalent → ask the user.
140
+
2. If the feature partially exists → check `git log` for prior sync commits to understand how similar cases were handled.
141
+
3. If a dependency isn't ported yet → skip and note it as a prerequisite in the batch checklist.
142
+
143
+
### Session changes require extra caution
144
+
145
+
The session subsystem (`ravendb/documents/session/`) spans 25+ modules and ~13K lines. Before porting session-related C# changes:
146
+
1. Read the target Python module thoroughly — session modules are tightly coupled.
147
+
2. Trace the full call chain from session API → command generation → request execution.
148
+
3. Session batches should be smaller (≤150 lines) due to higher coupling risk.
149
+
4. Always run the full session test suite after changes, not just new tests.
150
+
151
+
### Streaming operations
152
+
153
+
Streaming operations (bulk insert, subscriptions, query streaming) use generators and `concurrent.futures` — NOT the standard operation pattern. Fetch the full Python source for the existing streaming infrastructure before porting.
154
+
155
+
### Verification gate
156
+
157
+
After completing all batches, run:
158
+
1.`black --check .` — fix any formatting issues.
159
+
2.`python -m unittest <new_test_modules> -v` — all new tests must pass.
160
+
3.`python -m unittest discover` on affected test directories — confirm no regressions.
Follow the infrastructure and patterns in [TESTING.md](TESTING.md).
112
179
180
+
## If a batch fails
113
181
182
+
- If tests fail due to a bug in the port → fix in the same batch.
183
+
- If the feature can't be ported (missing dependency, server version mismatch) → revert the batch, add a `# todo: requires <dependency>` comment, and continue with remaining batches.
184
+
- Never leave broken code committed — each batch must be independently valid.
Copy file name to clipboardExpand all lines: .claude/skills/csharp-sync/TESTING.md
+4-6Lines changed: 4 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,10 +1,12 @@
1
1
# Testing Conventions
2
2
3
+
See CLAUDE.md for base testing infrastructure and common gotchas. This file covers only migration-specific testing patterns.
4
+
3
5
## Infrastructure
4
6
5
7
- All tests extend `TestBase` from `ravendb/tests/test_base.py`.
6
8
-`self.store` is pre-configured with a fresh database per test — no manual setup needed.
7
-
- Run tests: `.venv1\Scripts\python.exe -m unittest <module.path> -v`
9
+
- Run tests: `python -m unittest <module.path> -v`
8
10
9
11
## Assertion helpers
10
12
@@ -60,11 +62,7 @@ class _IndexResult:
60
62
61
63
Then query with `select_fields(_IndexResult, "Id", "Errors")`.
62
64
63
-
## Common gotchas
65
+
## Migration-specific testing notes
64
66
65
-
-**Datetime**: always `datetime.datetime.now(datetime.timezone.utc)`, never `utcnow()`.
66
-
-**Empty vs None**: server may return `[]` instead of `null` for empty collections — use `assertFalse`/`assertTrue` not `assertIsNone`/`assertIsNotNone`.
67
-
-**Exception messages**: the dispatcher wraps the full server error (message + stack trace) into the exception string — always use `assertRaisesWithMessageContaining` with a meaningful substring.
68
-
-**`RavenException.__init__`**: stores message as plain string in `args[0]`, not `(message, cause)` tuple.
69
67
-**Async operations**: use `store.maintenance.send_async(op)` → `op.wait_for_completion()` → `op.fetch_operations_status()["Result"]`.
0 commit comments