review-bench/davidortinau_sentencestudio/project-conventions

Claude Code and agent skill by review-bench/davidortinau_sentencestudio

Trust tier 3
  • community
Source check pending

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-conventions

SKILL.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

ProjectPurposeBuild
SentenceStudio.SharedCore: DbContext, repos, services, models, migrationsMulti-TFM
SentenceStudio.AppLibBlazor Hybrid library, Scriban templatesMulti-TFM
SentenceStudio.UIBlazor RCL — web pages, componentsdotnet build (no -f)
SentenceStudio.MacCatalyst/iOS/AndroidMAUI app heads-f net10.0-{platform}
SentenceStudio.ApiASP.NET Core backendnet10.0
SentenceStudio.WebAppBlazor Server frontendnet10.0
SentenceStudio.AppHostAspire orchestrationnet10.0
SentenceStudio.InfrastructureServer-side persistence (ServerDbContext)net10.0
SentenceStudio.WorkersBackground servicesnet10.0

Build Commands

bash
# MAUI (NEVER use dotnet run)
dotnet build -f net10.0-maccatalyst
dotnet build -t:Run -f net10.0-maccatalyst
# UI project (no TFM flag)
dotnet build src/SentenceStudio.UI/SentenceStudio.UI.csproj
# Tests
dotnet test

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 with card 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 EnsureCreatedAsync before MigrateAsync
  • 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) via AiService.SendPrompt<T>()
  • DTOs: Use [Description] attributes on properties — no [JsonPropertyName]
  • Connectivity: Check _connectivity.IsInternetAvailable before AI calls
  • Gateway: Optional IAiGatewayClient for server routing

Service Patterns

  • Constructor injection via IServiceProvider
  • All methods async (Task<T>)
  • ILogger<T> for structured logging
  • WeakReferenceMessenger.Default.Send() for cross-component messaging
  • Scoped DbContext access: _serviceProvider.CreateScope() → GetRequiredService<ApplicationDbContext>()

Error Handling

  • Structured logging: _logger.LogError(ex, "context {Field}", value)
  • InvalidOperationException for state violations
  • ArgumentException for 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 — when PlanItemId is null/empty the service creates a synthetic DailyPlanCompletion with PlanItemId = "adhoc-{guid}" so freeform sessions get duration tracking.
  • activityType string must parse to a PlanActivityType enum value or the ad-hoc row is silently dropped. Valid enum values (see IProgressService.cs): VocabularyReview, Reading, Listening, VideoWatching, Shadowing, Cloze, Translation, Writing, SceneDescription, Conversation, VocabularyGame. NOT valid: VocabularyMatching (use VocabularyGame), HowDoYouSay, WordAssociation, MinimalPairs.
  • ReconstructPlanFromDatabase filters adhoc-* so they don't show up in "Today's Plan"; GetActivityLogAsync includes 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/VocabMatching use plural ResourceIdsParam (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() not Top() / Bottom()
  • Use HStart() / HEnd() not Start() / 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 run for 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

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
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/review-bench/davidortinau_sentencestudio/project-conventions/badge)](https://verified-skill.com/skills/review-bench/davidortinau_sentencestudio/project-conventions)

Something wrong with this skill or its page? Tell us.