review-bench/davidortinau_sentencestudio/project-conventions
Claude Code and agent skill by review-bench/davidortinau_sentencestudio
- community
Checking that the SKILL.md file is still in the repository.
Core conventions and patterns for SentenceStudio
Install
npx vskill@latest install review-bench/davidortinau_sentencestudio/project-conventionsSKILL.md
Context
SentenceStudio is a .NET MAUI Blazor Hybrid language learning app. .NET 10 SDK (10.0.101), multi-platform (iOS, Android, Mac Catalyst), with .NET Aspire orchestration.
Project Structure
| Project | Purpose | Build | |
|---|---|---|---|
SentenceStudio.Shared | Core: DbContext, repos, services, models, migrations | Multi-TFM | |
SentenceStudio.AppLib | Blazor Hybrid library, Scriban templates | Multi-TFM | |
SentenceStudio.UI | Blazor RCL — web pages, components | dotnet build (no -f) | |
SentenceStudio.MacCatalyst/iOS/Android | MAUI app heads | -f net10.0-{platform} | |
SentenceStudio.Api | ASP.NET Core backend | net10.0 | |
SentenceStudio.WebApp | Blazor Server frontend | net10.0 | |
SentenceStudio.AppHost | Aspire orchestration | net10.0 | |
SentenceStudio.Infrastructure | Server-side persistence (ServerDbContext) | net10.0 | |
SentenceStudio.Workers | Background services | net10.0 |
Build Commands
Testing
- Framework: xUnit + Moq + FluentAssertions (Unit), AutoFixture (Integration), AspNetCore.Mvc.Testing (API)
- Projects:
tests/SentenceStudio.UnitTests,tests/SentenceStudio.IntegrationTests,tests/SentenceStudio.Api.Tests - Target: net10.0
Blazor Page Patterns
- Bootstrap icons only:
<i class="bi bi-{name}"></i>— NEVER emojis - Layout:
<PageHeader>→<ToolbarActions>→ main content withcard card-ss - Spinners:
<span class="spinner-border spinner-border-sm"> - Alerts:
<div class="alert alert-{danger|warning|success}"> - Auth:
@attribute [Authorize]on protected pages - Cleanup:
@implements IAsyncDisposable
Database Patterns
- DbContext:
ApplicationDbContext— SQLite on mobile, PostgreSQL on server - Table names: SINGULAR (configured in OnModelCreating)
- Synced entities: String GUID PKs with
ValueGeneratedNever() - Non-synced: Int auto-increment PKs
- Migrations: Always via
dotnet ef migrations add— NEVER hand-write, NEVER raw SQL ALTER TABLE - Data isolation: Filter by
UserProfileId - CRITICAL: Never call
EnsureCreatedAsyncbeforeMigrateAsync - Migration location:
Migrations/(PostgreSQL),Migrations/Sqlite/(mobile)
AI/Prompt Patterns
- Templates: 24+ Scriban templates in
src/SentenceStudio.AppLib/Resources/Raw/*.scriban-txt - Client:
IChatClient(Microsoft.Extensions.AI) viaAiService.SendPrompt<T>() - DTOs: Use
[Description]attributes on properties — no[JsonPropertyName] - Connectivity: Check
_connectivity.IsInternetAvailablebefore AI calls - Gateway: Optional
IAiGatewayClientfor server routing
Service Patterns
- Constructor injection via
IServiceProvider - All methods async (
Task<T>) ILogger<T>for structured loggingWeakReferenceMessenger.Default.Send()for cross-component messaging- Scoped DbContext access:
_serviceProvider.CreateScope()→GetRequiredService<ApplicationDbContext>()
Error Handling
- Structured logging:
_logger.LogError(ex, "context {Field}", value) InvalidOperationExceptionfor state violationsArgumentExceptionfor invalid arguments- Default/null returns for external API failures (TTS, image)
- Connectivity resilience via
ConnectivityChangedMessage
Activity tracking (ad-hoc + plan items)
- Every activity page calls
ActivityTimer.StartSession(activityType, PlanItemId, resourceId, skillId)unconditionally — whenPlanItemIdis null/empty the service creates a syntheticDailyPlanCompletionwithPlanItemId = "adhoc-{guid}"so freeform sessions get duration tracking. activityTypestring must parse to aPlanActivityTypeenum value or the ad-hoc row is silently dropped. Valid enum values (seeIProgressService.cs):VocabularyReview, Reading, Listening, VideoWatching, Shadowing, Cloze, Translation, Writing, SceneDescription, Conversation, VocabularyGame. NOT valid:VocabularyMatching(useVocabularyGame),HowDoYouSay,WordAssociation,MinimalPairs.ReconstructPlanFromDatabasefiltersadhoc-*so they don't show up in "Today's Plan";GetActivityLogAsyncincludes them so day-detail shows freeform practice with its own "Freeform practice" cluster.- Query param naming is NOT uniform: most pages use singular
ResourceIdParam;VocabQuiz/VocabMatchinguse pluralResourceIdsParam(comma-separated — take.Split(',').FirstOrDefault()for ad-hoc persistence).
Scriban prompt loops
Default iteration limit is 1000. Dynamic learning resources ("New Words") can return thousands of unpracticed terms. Any service rendering {{ for t in terms }} must cap the collection before passing to the template — current cap is 40 random words in TranslationService and ClozureService. If adding a new activity that loops vocab, apply the same cap.
MauiReactor Conventions
- Use
VStart()/VEnd()notTop()/Bottom() - Use
HStart()/HEnd()notStart()/End() - NEVER use
FillAndExpand— legacy pattern - NEVER put CollectionView inside scrollable containers
Anti-Patterns (CRITICAL)
- ❌ NEVER uninstall/reinstall apps (destroys user data)
- ❌ NEVER delete database files without permission + backup
- ❌ NEVER use
dotnet runfor MAUI apps - ❌ NEVER use emoji in UI/code/logs
- ❌ NEVER use raw SQL ALTER TABLE — always EF migrations
- ❌ NEVER suppress PendingModelChangesWarning
- ❌ NEVER put CollectionView inside VStack/scrollable containers
- ❌ NEVER use inline FontImageSource — define in ApplicationTheme.Icons.cs
- ❌ All documentation files go in
/docs/not repo root
Security
- Security scanPassed, 90 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryChecking.squad/skills/project-conventions/SKILL.md
Popularity
- 7-day trend score
- 0
Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/review-bench/davidortinau_sentencestudio/project-conventions)