Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .git-blame-ignore-revs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Formatting-only commits, ignored by GitHub blame and `git blame` (git config blame.ignoreRevsFile .git-blame-ignore-revs)

# Format MyApp.Client with Oxfmt
3961aa9878be57a2108dba2d5f48e31a055ae7b9
13 changes: 5 additions & 8 deletions .github/workflows/build-container.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,16 +65,13 @@ jobs:
echo "client_exists=false" >> $GITHUB_OUTPUT
fi

- name: Setup Node.js
- name: Setup Vite+ and install npm dependencies
if: steps.check_client.outputs.client_exists == 'true'
uses: actions/setup-node@v7
uses: voidzero-dev/setup-[email protected]
with:
node-version: 24

- name: Install npm dependencies
if: steps.check_client.outputs.client_exists == 'true'
working-directory: ./MyApp.Client
run: npm install
node-version: '24'
working-directory: ./MyApp.Client
cache: true

- name: Build client
if: steps.check_client.outputs.client_exists == 'true'
Expand Down
24 changes: 24 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,27 @@ jobs:
fi
working-directory: ./MyApp.Tests

client:
runs-on: ubuntu-latest
steps:
- name: checkout
uses: actions/checkout@v7

- name: Setup Vite+ and install npm dependencies
uses: voidzero-dev/[email protected]
with:
node-version: '24'
working-directory: ./MyApp.Client
cache: true

- name: check (format, lint, type check)
run: vp check
working-directory: ./MyApp.Client

- name: test
run: vp test run
working-directory: ./MyApp.Client

- name: build
run: vp build
working-directory: ./MyApp.Client
36 changes: 26 additions & 10 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,15 @@ A full-stack .NET 10 + React 19 + Vite template combining ServiceStack backend w
# Start both .NET and Vite dev servers (from project root)
dotnet watch

# After making changes to C# DTOs restart .NET before regenerating TypeScript DTOs by running:
# After changing C# DTOs, restart .NET: TypeScript DTOs (dtos.ts) are regenerated on startup.
# Manual regeneration is rarely needed (requires the .NET app to be running):
cd MyApp.Client && npm run dtos
```

### Building

```bash
# Build frontend (TypeScript + Vite)
# Build frontend (Vite+)
cd MyApp.Client && npm run build

# Build backend (.NET)
Expand All @@ -31,10 +32,23 @@ dotnet build
cd MyApp && npm run ui:build
```

### Checking (format, lint, type check)

The frontend uses the [Vite+](https://viteplus.dev) toolchain (`vp` CLI): Vite 8 (Rolldown), Vitest, Oxlint and Oxfmt.
All tool config (`lint`, `fmt`, `test`) lives in [vite.config.ts](MyApp.Client/vite.config.ts). There is no ESLint, Prettier or `tsc` step.

```bash
cd MyApp.Client && npm run check # Format + lint + type check (run before committing)
cd MyApp.Client && npm run lint # Lint + type check only (Oxlint)
cd MyApp.Client && npm run fmt # Format all files (Oxfmt)
```

`src/lib/dtos.ts` is generated, so it is excluded from lint and format.

### Testing

```bash
# Frontend tests (Vitest)
# Frontend tests (Vitest via Vite+), import from 'vite-plus/test'
cd MyApp.Client && npm run test # Watch mode
cd MyApp.Client && npm run test:ui # UI mode
cd MyApp.Client && npm run test:run # Single run
Expand Down Expand Up @@ -111,12 +125,12 @@ MyApp/ # .NET Backend (hosts both .NET and Vite React)
MyApp.Client/ # React Frontend
├── src/
│ ├── lib/
│ │ ├── dtos.ts # Auto-generated from C# (via `npm run dtos`)
│ │ ├── dtos.ts # Auto-generated from C# on .NET App startup
│ │ ├── gateway.ts # ServiceStack JsonServiceClient
│ │ └── utils.ts # Utility functions
│ ├── components/ # React components
│ └── styles/ # Tailwind CSS
└── vite.config.ts # Vite config for dev mode
└── vite.config.ts # Vite+ config: dev/build, lint, fmt, test

MyApp.ServiceModel/ # DTOs & API contracts
├── *.cs # C# Request/Response DTOs
Expand Down Expand Up @@ -260,13 +274,15 @@ ServiceStack's AutoQuery generates full CRUD APIs from declarative request DTOs.

### TypeScript DTO Generation

After changing C# DTOs in `MyApp.ServiceModel/`, restart the .NET Server then run:
`MyApp.Client/src/lib/dtos.ts` is regenerated automatically every time the .NET App starts (e.g. `dotnet run` or a `dotnet watch` restart).
This is done by the `dtos` StartupTask registered in [Configure.StartupTasks.GenerateDtos.cs](MyApp/Configure.StartupTasks.GenerateDtos.cs).
So after changing C# DTOs in `MyApp.ServiceModel/`, restarting the .NET Server is all that's needed, and the Vite dev server auto-reloads.

Running `npm run dtos` manually is unnecessary, but it's available if needed. It calls the running .NET App's `/types/typescript` endpoint to update `dtos.ts`:
```bash
cd MyApp.Client && npm run dtos
```

This calls ServiceStack's `/types/typescript` endpoint and updates `dtos.ts` with type-safe client DTOs. The Vite dev server auto-reloads.

### okai AutoQuery Code Generation

The `npx okai` tool generates C# AutoQuery APIs and migrations from TypeScript data models (`.d.ts` files):
Expand Down Expand Up @@ -577,8 +593,8 @@ Configured in [Configure.BackgroundJobs.cs](MyApp/Configure.BackgroundJobs.cs) u

1. **Start dev servers:** `dotnet watch` (starts both .NET and Vite)
2. **Make backend changes:** Edit C# files in `MyApp.ServiceModel` or `MyApp.ServiceInterface`
3. **Restart .NET Server**
4. **Regenerate DTOs:** `cd MyApp.Client && npm run dtos`
3. **Restart .NET Server:** this also regenerates `dtos.ts` (`npm run dtos` isn't needed)
4. **Use updated DTOs** from `@/lib/dtos` in the frontend
5. **Make frontend changes:** Edit React files in `MyApp.Client/src`
6. **Add new CRUD feature:**
- `npx okai init Feature`
Expand Down
23 changes: 0 additions & 23 deletions MyApp.Client/eslint.config.js

This file was deleted.

20 changes: 10 additions & 10 deletions MyApp.Client/index.html
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite App</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite App</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
Loading
Loading