|
| 1 | +## Configuration |
| 2 | + |
| 3 | +### Key Configuration Files |
| 4 | + |
| 5 | +- **MyApp/appsettings.json** - Application configuration |
| 6 | +- **MyApp.Client/next.config.mjs** - Next.js configuration |
| 7 | +- **MyApp.Client/styles/index.css** - Tailwind CSS configuration |
| 8 | +- **config/deploy.yml** - Kamal deployment settings |
| 9 | + |
| 10 | +### App Settings |
| 11 | + |
| 12 | +Configure in `appsettings.json` or environment: |
| 13 | + |
| 14 | +```json |
| 15 | +{ |
| 16 | + "ConnectionStrings": { |
| 17 | + "DefaultConnection": "DataSource=App_Data/app.db;Cache=Shared" |
| 18 | + }, |
| 19 | + "SmtpConfig": { |
| 20 | + "Host": "smtp.example.com", |
| 21 | + "Port": 587, |
| 22 | + |
| 23 | + "FromName": "MyApp" |
| 24 | + }, |
| 25 | + "AppConfig": { |
| 26 | + "BaseUrl": "https://myapp.example.com" |
| 27 | + } |
| 28 | +} |
| 29 | +``` |
| 30 | + |
| 31 | +### App Settings Secrets |
| 32 | + |
| 33 | +Instead of polluting each GitHub Reposity with multiple App-specific GitHub Action Secrets, you can save all your secrets in a single `APPSETTINGS_PATCH` GitHub Action Secret to patch `appsettings.json` with environment-specific configuration using [JSON Patch](https://jsonpatch.com). E.g: |
| 34 | + |
| 35 | +```json |
| 36 | +[ |
| 37 | + { |
| 38 | + "op":"replace", |
| 39 | + "path":"/ConnectionStrings/DefaultConnection", |
| 40 | + "value":"Server=service-postgres;Port=5432;User Id=dbuser;Password=dbpass;Database=dbname;Pooling=true;" |
| 41 | + }, |
| 42 | + { "op":"add", "path":"/SmtpConfig", "value":{ |
| 43 | + "UserName": "SmptUser", |
| 44 | + "Password": "SmptPass", |
| 45 | + "Host": "email-smtp.us-east-1.amazonaws.com", |
| 46 | + "Port": 587, |
| 47 | + |
| 48 | + "FromName": "MyApp", |
| 49 | + |
| 50 | + } |
| 51 | + }, |
| 52 | + { "op": "add", "path": "/Admins", "value": [ "[email protected]", "[email protected]"] }, |
| 53 | + { "op":"add", "path":"/CorsFeature/allowOriginWhitelist/-", "value":"https://servicestack.net" } |
| 54 | +] |
| 55 | +``` |
| 56 | + |
| 57 | +### SMTP Email |
| 58 | + |
| 59 | +Enable email sending by uncommenting in `Program.cs`: |
| 60 | + |
| 61 | +```csharp |
| 62 | +services.AddSingleton<IEmailSender<ApplicationUser>, EmailSender>(); |
| 63 | +``` |
| 64 | + |
| 65 | +## Upgrading to Enterprise Database |
| 66 | + |
| 67 | +To switch from SQLite to PostgreSQL/SQL Server/MySQL: |
| 68 | + |
| 69 | +1. Install preferred RDBMS (ef-postgres, ef-mysql, ef-sqlserver), e.g: |
| 70 | + |
| 71 | +:::sh |
| 72 | +npx add-in ef-postgres |
| 73 | +::: |
| 74 | + |
| 75 | +2. Install `db-identity` to use RDBMS `DatabaseJobsFeature` for background jobs and `DbRequestLogger` for Request Logs: |
| 76 | + |
| 77 | +:::sh |
| 78 | +npx add-in db-identity |
| 79 | +::: |
| 80 | + |
| 81 | +## AutoQuery CRUD Dev Workflow |
| 82 | + |
| 83 | +For Rapid Development simple [TypeScript Data Models](https://docs.servicestack.net/autoquery/okai-models) can be used to generate C# AutoQuery APIs and DB Migrations. |
| 84 | + |
| 85 | +### Cheat Sheet |
| 86 | + |
| 87 | +### Create a new Table |
| 88 | + |
| 89 | +Create a new Table use `init <Table>`, e.g: |
| 90 | + |
| 91 | +:::sh |
| 92 | +npx okai init Table |
| 93 | +::: |
| 94 | + |
| 95 | +This will generate an empty `MyApp.ServiceModel/<Table>.d.ts` file along with stub AutoQuery APIs and DB Migration implementations. |
| 96 | + |
| 97 | +### Use AI to generate the TypeScript Data Model |
| 98 | + |
| 99 | +Or to get you started quickly you can also use AI to generate the initial TypeScript Data Model with: |
| 100 | + |
| 101 | +:::sh |
| 102 | +npx okai "Table to store Customer Stripe Subscriptions" |
| 103 | +::: |
| 104 | + |
| 105 | +This launches a TUI that invokes ServiceStack's okai API to fire multiple concurrent requests to frontier cloud |
| 106 | +and OSS models to generate the TypeScript Data Models required to implement this feature. |
| 107 | +You'll be able to browse and choose which of the AI Models you prefer which you can accept by pressing `a` |
| 108 | +to `(a) accept`. These are the data models [Claude Sonnet 4.5 generated](https://servicestack.net/text-to-blazor?id=1764337230546) for this prompt. |
| 109 | + |
| 110 | +#### Regenerate AutoQuery APIs and DB Migrations |
| 111 | + |
| 112 | +After modifying the `Table.d.ts` TypeScript Data Model to include the desired fields, re-run the `okai` tool to re-generate the AutoQuery APIs and DB Migrations: |
| 113 | + |
| 114 | +:::sh |
| 115 | +npx okai Table.d.ts |
| 116 | +::: |
| 117 | + |
| 118 | +> Command can be run anywhere within your Solution |
| 119 | +
|
| 120 | +After you're happy with your Data Model you can run DB Migrations to run the DB Migration and create your RDBMS Table: |
| 121 | + |
| 122 | +:::sh |
| 123 | +npm run migrate |
| 124 | +::: |
| 125 | + |
| 126 | +#### Making changes after first migration |
| 127 | + |
| 128 | +If you want to make further changes to your Data Model, you can re-run the `okai` tool to update the AutoQuery APIs and DB Migrations, then run the `rerun:last` npm script to drop and re-run the last migration: |
| 129 | + |
| 130 | +:::sh |
| 131 | +npm run rerun:last |
| 132 | +::: |
| 133 | + |
| 134 | +#### Removing a Data Model and all generated code |
| 135 | + |
| 136 | +If you changed your mind and want to get rid of the RDBMS Table you can revert the last migration: |
| 137 | + |
| 138 | +:::sh |
| 139 | +npm run revert:last |
| 140 | +::: |
| 141 | + |
| 142 | +Which will drop the table and then you can get rid of the AutoQuery APIs, DB Migrations and TypeScript Data model with: |
| 143 | + |
| 144 | +:::sh |
| 145 | +npx okai rm Transaction.d.ts |
| 146 | +::: |
| 147 | + |
| 148 | +## Deployment |
| 149 | + |
| 150 | +### Docker + Kamal |
| 151 | + |
| 152 | +This project includes GitHub Actions for CI/CD with automatic Docker image builds and production [deployment with Kamal](https://docs.servicestack.net/kamal-deploy). The `/config/deploy.yml` configuration is designed to be reusable across projects—it dynamically derives service names, image paths, and volume mounts from environment variables, so you only need to configure your server's IP and hostname using GitHub Action secrets. |
| 153 | + |
| 154 | +### GitHub Action Secrets |
| 155 | + |
| 156 | +**Required - App Specific*: |
| 157 | + |
| 158 | +The only secret needed to be configured per Repository. |
| 159 | + |
| 160 | +| Variable | Example | Description | |
| 161 | +|----------|---------|-------------| |
| 162 | +| `KAMAL_DEPLOY_HOST` | `example.org` | Hostname used for SSL certificate and Kamal proxy | |
| 163 | + |
| 164 | +**Required** (Organization Secrets): |
| 165 | + |
| 166 | +Other Required variables can be globally configured in your GitHub Organization or User secrets which will |
| 167 | +enable deploying all your Repositories to the same server. |
| 168 | + |
| 169 | +| Variable | Example | Description | |
| 170 | +|----------|----------|-------------| |
| 171 | +| `KAMAL_DEPLOY_IP` | `100.100.100.100` | IP address of the server to deploy to | |
| 172 | +| `SSH_PRIVATE_KEY` | `ssh-rsa ...` | SSH private key to access the server | |
| 173 | +| `LETSENCRYPT_EMAIL` | `[email protected]` | Email for Let's Encrypt SSL certificate | |
| 174 | + |
| 175 | +**Optional**: |
| 176 | + |
| 177 | +| Variable | Example | Description | |
| 178 | +|----------|---------|-------------| |
| 179 | +| `SERVICESTACK_LICENSE` | `...` | ServiceStack license key | |
| 180 | + |
| 181 | +**Inferred** (from GitHub Action context): |
| 182 | + |
| 183 | +These are inferred from the GitHub Action context and don't need to be configured. |
| 184 | + |
| 185 | +| Variable | Source | Description | |
| 186 | +|----------|--------|-------------| |
| 187 | +| `GITHUB_REPOSITORY` | `${{ github.repository }}` | e.g. `acme/example.org` - used for service name and image | |
| 188 | +| `KAMAL_REGISTRY_USERNAME` | `${{ github.actor }}` | GitHub username for container registry | |
| 189 | +| `KAMAL_REGISTRY_PASSWORD` | `${{ secrets.GITHUB_TOKEN }}` | GitHub token for container registry auth | |
| 190 | + |
| 191 | +#### Features |
| 192 | + |
| 193 | +- **Docker containerization** with optimized .NET images |
| 194 | +- **SSL auto-certification** via Let's Encrypt |
| 195 | +- **GitHub Container Registry** integration |
| 196 | +- **Volume persistence** for App_Data including any SQLite database |
| 197 | + |
| 198 | +## AI-Assisted Development with CLAUDE.md |
| 199 | + |
| 200 | +As part of our objectives of improving developer experience and embracing modern AI-assisted development workflows - all new .NET SPA templates include a comprehensive `AGENTS.md` file designed to optimize AI-assisted development workflows. |
| 201 | + |
| 202 | +### What is CLAUDE.md? |
| 203 | + |
| 204 | +`CLAUDE.md` and [AGENTS.md](https://agents.md) onboards Claude (and other AI assistants) to your codebase by using a structured documentation file that provides it with complete context about your project's architecture, conventions, and technology choices. This enables more accurate code generation, better suggestions, and faster problem-solving. |
| 205 | + |
| 206 | +### What's Included |
| 207 | + |
| 208 | +Each template's `AGENTS.md` contains: |
| 209 | + |
| 210 | +- **Project Architecture Overview** - Technology stack, design patterns, and key architectural decisions |
| 211 | +- **Project Structure** - Gives Claude a map of the codebase |
| 212 | +- **ServiceStack Conventions** - DTO patterns, Service implementation, AutoQuery, Authentication, and Validation |
| 213 | +- **API Integration** - TypeScript DTO generation, API client usage, component patterns, and form handling |
| 214 | +- **Database Patterns** - OrmLite setup, migrations, and data access patterns |
| 215 | +- **Common Development Tasks** - Step-by-step guides for adding APIs, implementing features, and extending functionality |
| 216 | +- **Testing & Deployment** - Test patterns and deployment workflows |
| 217 | + |
| 218 | +### Extending with Project-Specific Details |
| 219 | + |
| 220 | +The existing `CLAUDE.md` serves as a solid foundation, but for best results, you should extend it with project-specific details like the purpose of the project, key parts and features of the project and any unique conventions you've adopted. |
| 221 | + |
| 222 | +### Benefits |
| 223 | + |
| 224 | +- **Faster Onboarding** - New developers (and AI assistants) understand project conventions immediately |
| 225 | +- **Consistent Code Generation** - AI tools generate code following your project's patterns |
| 226 | +- **Better Context** - AI assistants can reference specific ServiceStack patterns and conventions |
| 227 | +- **Reduced Errors** - Clear documentation of framework-specific conventions |
| 228 | +- **Living Documentation** - Keep it updated as your project evolves |
| 229 | + |
| 230 | +### How to Use |
| 231 | + |
| 232 | +Claude Code and most AI Assistants already support automatically referencing `CLAUDE.md` and `AGENTS.md` files, for others you can just include it in your prompt context when asking for help, e.g: |
| 233 | + |
| 234 | +> Using my project's AGENTS.md, can you help me add a new AutoQuery API for managing Products? |
| 235 | +
|
| 236 | +The AI will understand your App's ServiceStack conventions, React setup, and project structure, providing more accurate and contextual assistance. |
0 commit comments