Skip to content

Commit 053c561

Browse files
committed
Update AGENTS.md
1 parent bb03d0d commit 053c561

File tree

1 file changed

+31
-28
lines changed

1 file changed

+31
-28
lines changed

AGENTS.md

Lines changed: 31 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -102,28 +102,30 @@ This pattern keeps [Program.cs](MyApp/Program.cs) clean and separates concerns.
102102
### Project Structure
103103

104104
```
105-
MyApp/ # .NET Backend (hosts both .NET and React)
106-
├── Configure.*.cs # Modular AppHost configuration
107-
├── Migrations/ # EF Core Identity migrations + OrmLite app migrations
108-
├── Data/ # EF Core DbContext and Identity models
109-
└── wwwroot/ # Production static files (from MyApp.Client/dist)
105+
MyApp/ # .NET Backend (hosts both .NET and React)
106+
├── Configure.*.cs # Modular AppHost configuration
107+
├── Migrations/ # EF Core Identity migrations + OrmLite app migrations
108+
├── Pages/ # Identity Auth Razor Pages
109+
└── wwwroot/ # Production static files (from MyApp.Client/dist)
110110
111-
MyApp.Client/ # React Frontend
111+
MyApp.Client/ # React Frontend
112112
├── src/
113113
│ ├── lib/
114114
│ │ ├── dtos.ts # Auto-generated from C# (via `npm run dtos`)
115115
│ │ ├── gateway.ts # ServiceStack JsonServiceClient
116116
│ │ └── utils.ts # Utility functions
117117
│ ├── components/ # React components
118118
│ └── styles/ # Tailwind CSS
119-
└── vite.config.ts # API proxy config for dev mode
119+
└── vite.config.ts # Vite config for dev mode
120120
121121
MyApp.ServiceModel/ # DTOs & API contracts
122122
├── *.cs # C# Request/Response DTOs
123+
├── api.d.ts # TypeScript data models Schema
123124
└── *.d.ts # TypeScript data models for okai code generation
124125
125126
MyApp.ServiceInterface/ # Service implementations
126-
└── *Services.cs # ServiceStack service classes
127+
├── Data/ # EF Core DbContext and Identity models
128+
└── *Services.cs # ServiceStack service implementations
127129
128130
MyApp.Tests/ # .NET tests (NUnit)
129131
├── IntegrationTest.cs # API integration tests
@@ -133,7 +135,7 @@ MyApp.Tests/ # .NET tests (NUnit)
133135
### Database Architecture
134136

135137
**Dual ORM Strategy:**
136-
- **OrmLite**: All application data (faster, simpler, lighter typed ORM)
138+
- **OrmLite**: All application data (faster, simpler, typed POCO ORM)
137139
- **Entity Framework Core**: ASP.NET Core Identity tables only (Users, Roles, etc.)
138140

139141
Both use the same SQLite database by default (`App_Data/app.db`). Connection string in `appsettings.json`.
@@ -149,7 +151,7 @@ Run `npm run migrate` to execute both.
149151
1. ASP.NET Core Identity handles user registration/login via Razor Pages at `/Identity/*` routes
150152
2. ServiceStack AuthFeature integrates with Identity via `IdentityAuth.For<ApplicationUser>()` in [Configure.Auth.cs](MyApp/Configure.Auth.cs)
151153
3. Custom claims added via `AdditionalUserClaimsPrincipalFactory` and `CustomUserSession`
152-
4. ServiceStack services use `[ValidateHasRole]` attributes for authorization (see [Bookings.cs](MyApp.ServiceModel/Bookings.cs))
154+
4. ServiceStack services use `[ValidateIsAuthenticated]` and `[ValidateHasRole]` attributes for authorization (see [Bookings.cs](MyApp.ServiceModel/Bookings.cs))
153155

154156
### ServiceStack .NET APIs
155157

@@ -170,21 +172,21 @@ public class GetBookingResponse
170172
}
171173
```
172174

173-
The response type of an API should be specified in the `IReturn<Response>` marker interface. APIs which don't have any response should implement `IReturnVoid` instead.
175+
The response type of an API should be specified in the `IReturn<Response>` marker interface. APIs which don't return a response should implement `IReturnVoid` instead.
174176

175-
By convention APIs returning a single result have a `T? Result` property whilst APIs returning multiple results of the same type have a `List<T> Results` property. Otherwise it's encouraged to use intuitive property names for APIs returning results of different types in a flat structured Response DTO for simplicity.
177+
By convention, APIs return single results in a `T? Result` property, APIs returns multiple results of the same type in a `List<T> Results` property. Otherwise APIs returning results of different types should use intuitive property names in a flat structured Response DTO for simplicity.
176178

177-
These Server DTOs are what gets generated in `dtos.ts`.
179+
These C# Server DTOs are used to generate TypeScript `dtos.ts`.
178180

179181
#### Validating APIs
180182

181-
Any API Errors are automatically populated in the `ResponseStatus` property including when using [Declarative Validation Attributes](https://docs.servicestack.net/declarative-validation) like `[ValidateGreaterThan]` and `[ValidateNotEmpty]` which validate APIs and returned any structured error responses in `ResponseStatus`.
183+
Any API Errors are automatically populated in the `ResponseStatus` property, inc. [Declarative Validation Attributes](https://docs.servicestack.net/declarative-validation) like `[ValidateGreaterThan]` and `[ValidateNotEmpty]` which validate APIs and return any error responses in `ResponseStatus`.
182184

183185
#### Protecting APIs
184186

185187
The Type Validation Attributes below should be used to protect APIs:
186188

187-
- `[ValidateIsAuthenticated]` - Authenticated Users only
189+
- `[ValidateIsAuthenticated]` - Only Authenticated Users
188190
- `[ValidateIsAdmin]` - Only Admin Users
189191
- `[ValidateHasRole]` - Only Authenticated Users assigned with the specified role
190192
- `[ValidateApiKey]` - Only Users with a valid API Key
@@ -200,11 +202,11 @@ public class CreateBooking : ICreateDb<Booking>, IReturn<IdResponse>
200202

201203
#### Primary HTTP Method
202204

203-
APIs have a primary HTTP Method which if not specified uses HTTP **POST**. Use `IGet`, `IPost`, `IPut` or `IDelete` to change the HTTP Verb except for AutoQuery APIs which have implied verbs for each operation.
205+
APIs have a primary HTTP Method which if not specified uses HTTP **POST**. Use `IGet`, `IPost`, `IPut`, `IPatch` or `IDelete` to change the HTTP Verb except for AutoQuery APIs which have implied verbs for each CRUD operation.
204206

205207
#### API Implementations
206208

207-
Implementations of ServiceStack APIs should be added to the `MyApp.ServiceInterface` folder, e.g:
209+
ServiceStack API implementations should be added to `MyApp.ServiceInterface/`:
208210

209211
```csharp
210212
//MyApp.ServiceInterface/BookingServices.cs
@@ -228,11 +230,12 @@ public class BookingServices(IAutoQueryDb autoquery) : Service
228230
}
229231
```
230232

231-
APIs can be implemented with **sync** or **async** methods. The return type of an API implementation does not change behavior however it's encouraged to use `object` to encourage
233+
APIs can be implemented with **sync** or **async** methods using `Any` or its primary HTTP Method e.g. `Get`, `Post`.
234+
The return type of an API implementation does not change behavior however returning `object` is recommended so its clear the Request DTO `IReturn<Response>` interface defines the APIs Response type and Service Contract.
232235

233-
The ServiceStack `Service` base class has convenience properties like `Db` to resolve an Open `IDbConnection` for that API and `base.Request` to resolve the `IRequest` context. All other dependencies required by the API should use a Primary Constructor with constructor injection.
236+
The ServiceStack `Service` base class has convenience properties like `Db` to resolve an Open `IDbConnection` for that API and `base.Request` to resolve the `IRequest` context. All other dependencies required by the API should use constructor injection in a Primary Constructor.
234237

235-
A ServiceStack API typically returns the Response DTO defined in its Request DTO `IReturn<Response>` or an Error but can also return any [custom Return Type](https://docs.servicestack.net/service-return-types) like a raw `string`, `byte[]`, `Stream`, `IStreamWriter`, `HttpResult` and `HttpError`.
238+
A ServiceStack API typically returns the Response DTO defined in its Request DTO `IReturn<Response>` or an Error but can also return any raw [custom Return Type](https://docs.servicestack.net/service-return-types) like `string`, `byte[]`, `Stream`, `IStreamWriter`, `HttpResult` and `HttpError`.
236239

237240
### AutoQuery CRUD Pattern
238241

@@ -249,12 +252,12 @@ ServiceStack's AutoQuery generates full CRUD APIs from declarative request DTOs.
249252

250253
### TypeScript DTO Generation
251254

252-
After changing C# DTOs in `MyApp.ServiceModel/`, run:
255+
After changing C# DTOs in `MyApp.ServiceModel/`, restart the .NET Server then run:
253256
```bash
254257
cd MyApp.Client && npm run dtos
255258
```
256259

257-
This calls ServiceStack's `/types/typescript` endpoint and updates `MyApp.Client/src/lib/dtos.ts` with type-safe client DTOs. The Vite dev server auto-reloads.
260+
This calls ServiceStack's `/types/typescript` endpoint and updates `dtos.ts` with type-safe client DTOs. The Vite dev server auto-reloads.
258261

259262
### okai AutoQuery Code Generation
260263

@@ -357,7 +360,7 @@ AutoQuery also matches on pluralized fields where `Ids` matches `Id` and applies
357360
const api = client.api(new QueryBookings({ ids:[1,2,3] }))
358361
```
359362

360-
Multiple Request DTO properties applies mutliple **AND** Filters, e.g:
363+
Multiple Request DTO properties applies mutliple **AND** filters, e.g:
361364

362365
```typescript
363366
const api = client.api(new QueryBookings({ minCost:100, ids:[1,2,3] }))
@@ -380,7 +383,7 @@ const response = await client.api(new QueryBookings())
380383

381384
The `client` is a configured `JsonServiceClient` pointing to `/api` (proxied to .NET backend).
382385

383-
All .NET APIs are accessible by Request DTOs which implement a `IReturn<ResponseType>` or a `IReturnVoid` interface which defines the Response of an API, e.g:
386+
All .NET APIs are accessible by Request DTOs which implement either a `IReturn<ResponseType>` a `IReturnVoid` interface which defines the API Response, e.g:
384387

385388
```typescript
386389
export class Hello implements IReturn<HelloResponse>, IGet
@@ -397,7 +400,7 @@ export class HelloResponse
397400

398401
### ServiceStack API Client Pattern
399402

400-
Inside a React Component use `useClient()` to resolve a Service Client. The `ApiResult` can be used to hold **loading**, **failed** and **successful** API Response states, e.g:
403+
Inside a React Component use `useClient()` to resolve a Service Client. The `ApiResult` can hold **loading**, **failed** and **successful** API Response states, e.g:
401404

402405
```typescript
403406
type Props = { value: string }
@@ -439,12 +442,12 @@ if (api.succeeded) {
439442
}
440443
```
441444
442-
The `apiForm` API can use a HTML Form's FormData for its Request Body together with the APIs **empty Request DTO**, e.g:
445+
The `apiForm` API can use a HTML Form's FormData for its Request Body together with an APIs **empty Request DTO**, e.g:
443446
444447
```typescript
445448
const submit = async (e: React.FormEvent) => {
446-
const form = e.currentTarget as HTMLFormElement
447-
const api = await client.apiForm(new CreateContact(), new FormData(form))
449+
const form = e.currentTarget as HTMLFormElement
450+
const api = await client.apiForm(new CreateContact(), new FormData(form))
448451
if (api.succeeded) {
449452
console.log(`The API succeded:`, api.response)
450453
} else if (api.error) {

0 commit comments

Comments
 (0)