Skip to content

Commit 901e5ca

Browse files
committed
update: added skill files
1 parent b03be39 commit 901e5ca

File tree

20 files changed

+1848
-0
lines changed

20 files changed

+1848
-0
lines changed

.cursor/rules/README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Cursor (optional)
2+
3+
**Cursor** users: start at **[AGENTS.md](../../AGENTS.md)**. All conventions live in **`skills/*/SKILL.md`**.
4+
5+
This folder only points contributors to **`AGENTS.md`** so editor-specific config does not duplicate the canonical docs.

AGENTS.md

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# Contentstack .NET SDK – Agent guide
2+
3+
**Universal entry point** for contributors and AI agents. Each skill has a short **`skills/*/SKILL.md`** entry; exhaustive patterns, checklists, and examples live in **`skills/*/references/*.md`** where present.
4+
5+
## What this repo is
6+
7+
| Field | Detail |
8+
|-------|--------|
9+
| **Name:** | [contentstack-dotnet](https://github.com/contentstack/contentstack-dotnet) |
10+
| **Purpose:** | .NET SDK for Contentstack’s Content Delivery API (CDA)—fetch entries, assets, and run queries from .NET apps. |
11+
| **Out of scope (if any):** | Do not bypass the SDK HTTP layer with ad-hoc `HttpClient` usage; all requests go through `HttpRequestHandler` (see `skills/sdk-core-patterns/SKILL.md`). |
12+
13+
## Tech stack (at a glance)
14+
15+
| Area | Details |
16+
|------|---------|
17+
| Language | C#; multi-targeting includes `netstandard2.0`, `net47`, `net472` (see project files under `Contentstack.Core/`). |
18+
| Build | .NET SDK — solution [`Contentstack.Net.sln`](Contentstack.Net.sln); packages [`Contentstack.Core/`](Contentstack.Core/) (Delivery SDK), [`Contentstack.AspNetCore/`](Contentstack.AspNetCore/) (DI extensions). |
19+
| Tests | xUnit; unit tests in [`Contentstack.Core.Unit.Tests/`](Contentstack.Core.Unit.Tests/) (no credentials); integration tests in [`Contentstack.Core.Tests/`](Contentstack.Core.Tests/) (requires `app.config` / API credentials). |
20+
| Lint / coverage | No dedicated repo-wide lint/format CLI in CI. Security/static analysis: [CodeQL workflow](.github/workflows/codeql-analysis.yml). |
21+
| Other | JSON: Newtonsoft.Json; package version: single source in [`Directory.Build.props`](Directory.Build.props). |
22+
23+
## Commands (quick reference)
24+
25+
| Command type | Command |
26+
|--------------|---------|
27+
| Build | `dotnet build Contentstack.Net.sln` |
28+
| Test (unit) | `dotnet test Contentstack.Core.Unit.Tests/Contentstack.Core.Unit.Tests.csproj` |
29+
| Test (integration) | `dotnet test Contentstack.Core.Tests/Contentstack.Core.Tests.csproj` (configure credentials locally) |
30+
31+
CI: [`.github/workflows/unit-test.yml`](.github/workflows/unit-test.yml) restores, builds, and runs unit tests on Windows (.NET 7). Other workflows include [NuGet publish](.github/workflows/nuget-publish.yml), [branch checks](.github/workflows/check-branch.yml), [CodeQL](.github/workflows/codeql-analysis.yml), policy/SCA scans.
32+
33+
## Where the documentation lives: skills
34+
35+
| Skill | Path | What it covers |
36+
|-------|------|----------------|
37+
| Dev workflow | [`skills/dev-workflow/SKILL.md`](skills/dev-workflow/SKILL.md) | Solution layout, build/test commands, versioning, CI entry points. |
38+
| SDK core patterns | [`skills/sdk-core-patterns/SKILL.md`](skills/sdk-core-patterns/SKILL.md) | Architecture, `ContentstackClient`, HTTP layer, DI, plugins. |
39+
| Query building | [`skills/query-building/SKILL.md`](skills/query-building/SKILL.md) | Fluent query API, operators, pagination, sync, taxonomy. |
40+
| Models and serialization | [`skills/models-and-serialization/SKILL.md`](skills/models-and-serialization/SKILL.md) | Entry/Asset models, JSON converters, collections. |
41+
| Error handling | [`skills/error-handling/SKILL.md`](skills/error-handling/SKILL.md) | Exception hierarchy, `ErrorMessages`, API error parsing. |
42+
| Testing | [`skills/testing/SKILL.md`](skills/testing/SKILL.md) | Unit vs integration tests, AutoFixture, `IntegrationTestBase`. |
43+
| Code review | [`skills/code-review/SKILL.md`](skills/code-review/SKILL.md) | PR checklist for this SDK. |
44+
45+
An index with “when to use” hints is in [`skills/README.md`](skills/README.md).
46+
47+
## Using Cursor (optional)
48+
49+
If you use **Cursor**, [`.cursor/rules/README.md`](.cursor/rules/README.md) only points to **`AGENTS.md`**—the same conventions as for everyone else. Canonical guidance remains in **`skills/*/SKILL.md`** and **`skills/*/references/`**.

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
.NET SDK for Contentstack's Content Delivery API
55

6+
Contributor and agent conventions: see **[AGENTS.md](AGENTS.md)**.
7+
68
## Getting Started
79

810
This guide will help you get started with our .NET SDK to build apps powered by Contentstack.

skills/README.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Skills – Contentstack .NET SDK
2+
3+
Source of truth for detailed guidance. Read **[AGENTS.md](../AGENTS.md)** first, then open the skill that matches your task.
4+
5+
## When to use which skill
6+
7+
| Skill folder | Use when |
8+
|--------------|----------|
9+
| `dev-workflow` | Building the solution, versioning, CI workflows, onboarding, PR prep. |
10+
| `sdk-core-patterns` | Architecture, `ContentstackClient`, HTTP layer, DI, plugins, request flow. |
11+
| `query-building` | Query operators, fluent API, pagination, sync, taxonomy, `Query.cs`. |
12+
| `models-and-serialization` | Entry/Asset models, JSON converters, `ContentstackCollection`, serialization. |
13+
| `error-handling` | Exceptions, `ErrorMessages`, parsing API errors. |
14+
| `testing` | Writing or debugging unit/integration tests, coverage, test layout. |
15+
| `code-review` | Reviewing a PR against SDK-specific checklist. |
16+
17+
Each folder contains **`SKILL.md`** with YAML frontmatter (`name`, `description`) for agent discovery. Long-form content is under **`references/`** when applicable—open `SKILL.md` first, then follow links.
18+
19+
### Cursor
20+
21+
In Cursor, you can also reference a skill in chat with `@skills/<folder-name>` (for example `@skills/testing`).

skills/code-review/SKILL.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
---
2+
name: code-review
3+
description: SDK-specific PR review checklist for the Contentstack .NET SDK — covers breaking changes, HTTP layer correctness, exception handling, serialization, fluent API patterns, configuration, test coverage, multi-targeting, plugin lifecycle, and internal visibility. Use when reviewing pull requests, examining code changes, or performing code quality assessments on this SDK.
4+
---
5+
6+
# Code Review
7+
8+
## When to use
9+
10+
- Reviewing a PR or diff against SDK conventions.
11+
- Self-review before opening a PR.
12+
13+
## Severity levels
14+
15+
- **Critical** — Must fix before merge (correctness, breaking changes, security)
16+
- **Important** — Should fix (maintainability, SDK patterns, consistency)
17+
- **Suggestion** — Consider improving (style, optimization)
18+
19+
Category-by-category checklists (breaking changes, HTTP, exceptions, serialization, fluent API, config, tests, multi-targeting, plugins, visibility) live in the reference docs below—not duplicated here.
20+
21+
## Reference
22+
23+
| Document | Contents |
24+
|----------|----------|
25+
| [references/code-review-checklist.md](references/code-review-checklist.md) | Full markdown checklists per area |
26+
| [references/red-flags.md](references/red-flags.md) | Short anti-pattern list for quick scan |
Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
# Code Review Checklist
2+
3+
## Breaking Changes Checklist
4+
5+
```markdown
6+
## Breaking Changes Review
7+
- [ ] No public method signatures removed or changed without [Obsolete] deprecation
8+
- [ ] No [JsonProperty] values changed (would break consumer deserialization silently)
9+
- [ ] No ContentstackOptions public property removed
10+
- [ ] New required options have defaults (don't break existing consumers who don't set them)
11+
- [ ] No namespace renames without backward-compatible type aliases
12+
- [ ] No IContentstackPlugin interface signature changed
13+
- [ ] Version bump planned if breaking change is intentional (Directory.Build.props)
14+
```
15+
16+
## HTTP Layer Checklist
17+
18+
```markdown
19+
## HTTP Layer Review
20+
- [ ] All HTTP calls route through HttpRequestHandler.ProcessRequest
21+
- [ ] No HttpClient instantiation anywhere in the PR
22+
- [ ] New query params added to UrlQueries dict (not directly to URL string)
23+
- [ ] New field-level filters added to QueryValueJson dict
24+
- [ ] New headers added via Headers parameter to ProcessRequest
25+
- [ ] Branch header uses "branch" key, passed as separate Branch parameter
26+
- [ ] No hardcoded URLs — BaseUrl comes from Config.BaseUrl
27+
- [ ] Live preview URL resolved via Config.getBaseUrl() — not hardcoded
28+
- [ ] ProcessRequest result (string JSON) parsed, not further HTTP calls made
29+
```
30+
31+
## Exception Handling Checklist
32+
33+
```markdown
34+
## Exception Handling Review
35+
- [ ] Domain-specific exception type used (QueryFilterException, AssetException, etc.)
36+
- [ ] No bare `throw new Exception(...)` or `throw new ContentstackException(...)`
37+
- [ ] All message strings sourced from ErrorMessages.cs constants
38+
- [ ] No string literals in throw statements
39+
- [ ] GetContentstackError(ex) called when catching WebException from HTTP calls
40+
- [ ] ErrorCode, StatusCode, Errors preserved when re-wrapping exceptions
41+
- [ ] New domain area has new exception class with factory methods
42+
- [ ] New error messages added to correct section in ErrorMessages.cs
43+
- [ ] FormatExceptionDetails(innerEx) used in ProcessingError factory methods
44+
```
45+
46+
## Serialization Checklist
47+
48+
```markdown
49+
## Serialization Review
50+
- [ ] All public properties mapping CDA JSON fields have [JsonProperty("snake_case")]
51+
- [ ] No reliance on default Newtonsoft.Json camelCase or PascalCase matching
52+
- [ ] Custom deserialization uses [CSJsonConverter] + JsonConverter subclass
53+
- [ ] JsonConverter placed in Contentstack.Core/Internals/ (internal class)
54+
- [ ] No System.Text.Json usage
55+
- [ ] No JsonConvert.DeserializeObject with hardcoded type outside of converter
56+
- [ ] ContentstackCollection<T> used for list responses (not List<T> directly)
57+
- [ ] "entries" token used for entry collection, "assets" for asset collection
58+
```
59+
60+
## Fluent API Checklist
61+
62+
```markdown
63+
## Fluent API Review
64+
- [ ] Every Query filter/operator method returns `return this;`
65+
- [ ] Null key validated at start of method → QueryFilterException.Create()
66+
- [ ] Empty string key validated → QueryFilterException.Create()
67+
- [ ] Operator value stored in QueryValueJson[key][$operator] nested dict
68+
- [ ] URL-level params stored in UrlQueries[key]
69+
- [ ] Method name follows verb+noun pattern (GreaterThan, ContainedIn, NotExists)
70+
- [ ] No mutation of QueryValueJson or UrlQueries outside of the Query class itself
71+
- [ ] And()/Or() accept Query[] (not raw dictionaries)
72+
```
73+
74+
## Configuration Checklist
75+
76+
```markdown
77+
## Configuration Review
78+
- [ ] New options added to ContentstackOptions (public class), not Config (internal)
79+
- [ ] New property has XML <summary> doc comment
80+
- [ ] Default value set in ContentstackOptions() constructor or property initializer
81+
- [ ] ContentstackClient constructor reads new option and passes to Config
82+
- [ ] Config never exposed as public property
83+
- [ ] New option tested in ContentstackOptionsUnitTests.cs
84+
- [ ] ASP.NET Core binding works (IOptions<ContentstackOptions> path verified)
85+
```
86+
87+
## Test Coverage Checklist
88+
89+
```markdown
90+
## Test Coverage Review
91+
- [ ] Unit test for each new public Query method (QueryValueJson assertion via reflection)
92+
- [ ] Unit test for null key input → QueryFilterException
93+
- [ ] Unit test for empty key input → QueryFilterException
94+
- [ ] Unit test for fluent return (Assert.Equal(query, result))
95+
- [ ] Integration test file in Integration/{FeatureName}Tests/ subfolder
96+
- [ ] Integration test class extends IntegrationTestBase
97+
- [ ] Integration test constructor takes ITestOutputHelper output
98+
- [ ] CreateClient() used (not manual ContentstackClient construction)
99+
- [ ] LogArrange/LogAct/LogAssert used in correct order
100+
- [ ] TestAssert.* used (not raw Assert.*)
101+
- [ ] [Fact(DisplayName = "FeatureArea - Component Description")] present
102+
- [ ] Happy path test (valid params → expected response)
103+
- [ ] Error path test (invalid params or not found → expected exception)
104+
```
105+
106+
## Multi-Targeting Checklist
107+
108+
```markdown
109+
## Multi-Targeting Review
110+
- [ ] No HttpClient (netstandard2.0 HttpClient has behavioural differences from net4x)
111+
- [ ] No System.Text.Json (not available without separate package in netstandard2.0)
112+
- [ ] No record types (C# 9, requires LangVersion setting for net47/net472)
113+
- [ ] No default interface implementations (C# 8, may affect net47)
114+
- [ ] No nullable reference types without #nullable enable guard
115+
- [ ] No top-level statements (not applicable to library projects but worth checking)
116+
- [ ] Tested compile against netstandard2.0 target (or verified via CI)
117+
```
118+
119+
## Plugin Lifecycle Checklist
120+
121+
```markdown
122+
## Plugin Lifecycle Review
123+
- [ ] New feature that makes HTTP calls uses HttpRequestHandler (plugins run automatically)
124+
- [ ] No WebRequest.Create() called directly in new model classes
125+
- [ ] IContentstackPlugin interface not modified (breaking for all plugin consumers)
126+
- [ ] RequestLoggingPlugin still works with any new request/response changes
127+
- [ ] Plugin.OnRequest receives HttpWebRequest before send
128+
- [ ] Plugin.OnResponse receives response string (can mutate/inspect)
129+
```
130+
131+
## Internal Visibility Checklist
132+
133+
```markdown
134+
## Internal Visibility Review
135+
- [ ] New utility/helper classes in Internals/ are marked `internal`
136+
- [ ] New model types intended for consumers are in Models/ and `public`
137+
- [ ] New configuration types are in Configuration/ and `public`
138+
- [ ] No public exposure of Config, HttpRequestHandler, or VersionUtility
139+
- [ ] InternalsVisibleTo not modified (already covers both test projects)
140+
- [ ] New internal methods accessible in unit tests without changes
141+
```
142+
143+
## Common Issues Found in Past PRs
144+
145+
### Silent Deserialization Failures
146+
`[JsonProperty]` omitted → field is always null at runtime, no exception. Verify all properties that map CDA JSON fields.
147+
148+
### Exception Message in Throw
149+
```csharp
150+
// Bad
151+
throw new QueryFilterException("Please provide valid params.");
152+
153+
// Good
154+
throw QueryFilterException.Create(innerEx);
155+
// or
156+
throw new QueryFilterException(ErrorMessages.QueryFilterError);
157+
```
158+
159+
### Hardcoded Environment
160+
```csharp
161+
// Bad — breaks for consumers with different environments
162+
mainJson["environment"] = "production";
163+
164+
// Correct — already done in Exec()
165+
mainJson["environment"] = ContentTypeInstance.StackInstance.Config.Environment;
166+
```
167+
168+
### Returning void from Query Method
169+
```csharp
170+
// Bad — breaks fluent chaining
171+
public void SetMyParam(string value) { UrlQueries["my_param"] = value; }
172+
173+
// Good
174+
public Query SetMyParam(string value) { UrlQueries["my_param"] = value; return this; }
175+
```
176+
177+
### Dictionary Not Initialized for QueryValueJson Entry
178+
```csharp
179+
// Bad — throws KeyNotFoundException or InvalidCastException
180+
((Dictionary<string, object>)QueryValueJson[key])["$op"] = value;
181+
182+
// Good — guard with ContainsKey
183+
if (!QueryValueJson.ContainsKey(key))
184+
QueryValueJson[key] = new Dictionary<string, object>();
185+
((Dictionary<string, object>)QueryValueJson[key])["$op"] = value;
186+
```
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# SDK-specific red flags
2+
3+
Quick scan for anti-patterns in PRs:
4+
5+
```
6+
❌ new HttpClient() — use HttpRequestHandler
7+
❌ throw new Exception("message") — use typed ContentstackException subclass
8+
❌ "hardcoded_field_name" — use [JsonProperty] or ErrorMessages constant
9+
❌ public Config GetConfig() — Config is internal by design
10+
❌ return void — Query methods return Query (fluent)
11+
❌ [JsonProperty] omitted — CDA uses snake_case; PascalCase won't deserialize
12+
❌ <Version> in .csproj — use Directory.Build.props
13+
```
14+
15+
For full category-by-category review, use [code-review-checklist.md](code-review-checklist.md).

skills/dev-workflow/SKILL.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
---
2+
name: dev-workflow
3+
description: Local development and CI workflow for the Contentstack .NET SDK — solution layout, dotnet build/test commands, package versioning in Directory.Build.props, GitHub Actions (unit tests, CodeQL, NuGet), and integration test credentials. Use when onboarding, running builds, preparing a PR, or finding where CI is defined.
4+
---
5+
6+
# Dev workflow – Contentstack .NET SDK
7+
8+
## When to use
9+
10+
- Onboarding, building, or running tests locally.
11+
- Finding which workflow applies to PRs, releases, or security scans.
12+
- Maintainer tasks: DocFX, NuGet publish expectations.
13+
14+
## Invariants
15+
16+
- Version in **`Directory.Build.props`** only for package version.
17+
- Integration tests need **`app.config`** (or equivalent) — do not commit secrets.
18+
19+
## Reference
20+
21+
| Document | Contents |
22+
|----------|----------|
23+
| [references/repo-tooling.md](references/repo-tooling.md) | Commands, CI, branch policy, CodeQL, NuGet release workflow, DocFX, SCA/policy scans, project layout |
24+
25+
## Related skills
26+
27+
- [SDK core patterns](../sdk-core-patterns/SKILL.md) — architecture and HTTP.
28+
- [Testing](../testing/SKILL.md) — unit vs integration patterns and credentials.

0 commit comments

Comments
 (0)