Files
ClaudeDo/src/ClaudeDo.Data/Configuration/AppSettingsEntityConfiguration.cs
T
mika kuns 69898be5c9 feat(usage): PowerUse-Zeitfenster + Handoff-Schwellwert als Settings
Drei neue app_settings-Spalten (Migration AddPowerUseWindow):
power_use_window_start/end (HH:mm, lokal, nullable) und
power_use_handoff_pct (NOT NULL DEFAULT 95, geclampt 50-99).

Die Fensterlogik liegt als reine Funktion in PowerUseWindow
(Contains/Normalize/IsOpen): beide Grenzen leer oder nur eine gesetzt =
rund um die Uhr, Ende vor Start wrappt ueber Mitternacht, Grenzen
halboffen. Geprueft wird in ComposeHandlerPromptAsync, also pro Phase
zum Zeitpunkt des Prompt-Baus - die Uhr ist per Func<DateTime>
injizierbar. Bedienung im Usage-Monitor neben dem PowerUse-Toggle
(Commit auf Blur/Enter, ein Write fuer alle vier Felder); in
Settings->General unsichtbar, aber load->save durchgereicht.

Nebenbefund, gleicher Pfad: AppSettingsRepository.UpdateAsync kopiert
Feld fuer Feld und hat ModelPresets, PowerUseEnabled und
ListHandlerMaxHandoffs nie geschrieben - jeder Save dieser drei war
still wirkungslos. Mit ergaenzt und per Round-trip-Test gepinnt.
2026-09-02 19:09:47 +02:00

87 lines
4.4 KiB
C#

using ClaudeDo.Data.Models;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace ClaudeDo.Data.Configuration;
public class AppSettingsEntityConfiguration : IEntityTypeConfiguration<AppSettingsEntity>
{
public void Configure(EntityTypeBuilder<AppSettingsEntity> builder)
{
builder.ToTable("app_settings");
builder.HasKey(s => s.Id);
builder.Property(s => s.Id).HasColumnName("id").ValueGeneratedNever();
builder.Property(s => s.NextTaskNumber)
.HasColumnName("next_task_number").IsRequired().HasDefaultValue(1);
builder.Property(s => s.DefaultClaudeInstructions)
.HasColumnName("default_claude_instructions").IsRequired().HasDefaultValue(string.Empty);
builder.Property(s => s.DefaultModel)
.HasColumnName("default_model").IsRequired().HasDefaultValue("sonnet");
builder.Property(s => s.DefaultMaxTurns)
.HasColumnName("default_max_turns").IsRequired().HasDefaultValue(40);
builder.Property(s => s.DefaultPermissionMode)
.HasColumnName("default_permission_mode").IsRequired().HasDefaultValue("bypassPermissions");
builder.Property(s => s.MaxTurnsCeiling)
.HasColumnName("max_turns_ceiling").IsRequired().HasDefaultValue(80);
builder.Property(s => s.MaxParallelExecutions)
.HasColumnName("max_parallel_executions").IsRequired().HasDefaultValue(1);
builder.Property(s => s.WorktreeStrategy)
.HasColumnName("worktree_strategy").IsRequired().HasDefaultValue("sibling");
builder.Property(s => s.CentralWorktreeRoot)
.HasColumnName("central_worktree_root");
builder.Property(s => s.WorktreeAutoCleanupEnabled)
.HasColumnName("worktree_auto_cleanup_enabled").IsRequired().HasDefaultValue(false);
builder.Property(s => s.WorktreeAutoCleanupDays)
.HasColumnName("worktree_auto_cleanup_days").IsRequired().HasDefaultValue(7);
builder.Property(s => s.RepoImportFolders)
.HasColumnName("repo_import_folders");
builder.Property(s => s.ReportExcludedPaths).HasColumnName("report_excluded_paths");
builder.Property(s => s.StandupWeekday).HasColumnName("standup_weekday")
.IsRequired().HasDefaultValue((int)DayOfWeek.Wednesday);
builder.Property(s => s.DailyPrepMaxTasks)
.HasColumnName("daily_prep_max_tasks").IsRequired().HasDefaultValue(5);
builder.Property(s => s.SessionSkills).HasColumnName("session_skills");
builder.Property(s => s.ModelPresets).HasColumnName("model_presets");
builder.Property(s => s.UsageGateFiveHourPct)
.HasColumnName("usage_gate_five_hour_pct").IsRequired().HasDefaultValue(80);
builder.Property(s => s.UsageGateSevenDayPct)
.HasColumnName("usage_gate_seven_day_pct").IsRequired().HasDefaultValue(90);
builder.Property(s => s.UsageThrottleFiveHourSoftPct)
.HasColumnName("usage_throttle_five_hour_soft_pct").IsRequired().HasDefaultValue(50);
builder.Property(s => s.UsageThrottleFiveHourHardPct)
.HasColumnName("usage_throttle_five_hour_hard_pct").IsRequired().HasDefaultValue(65);
builder.Property(s => s.UsageThrottleSevenDaySoftPct)
.HasColumnName("usage_throttle_seven_day_soft_pct").IsRequired().HasDefaultValue(50);
builder.Property(s => s.UsageThrottleSevenDayHardPct)
.HasColumnName("usage_throttle_seven_day_hard_pct").IsRequired().HasDefaultValue(65);
builder.Property(s => s.AutoContinueOnUsageLimit)
.HasColumnName("auto_continue_on_usage_limit").IsRequired().HasDefaultValue(false);
builder.Property(s => s.PowerUseEnabled)
.HasColumnName("power_use_enabled").IsRequired().HasDefaultValue(false);
builder.Property(s => s.PowerUseWindowStart)
.HasColumnName("power_use_window_start");
builder.Property(s => s.PowerUseWindowEnd)
.HasColumnName("power_use_window_end");
builder.Property(s => s.PowerUseHandoffPct)
.HasColumnName("power_use_handoff_pct").IsRequired().HasDefaultValue(95);
builder.Property(s => s.ListHandlerMaxHandoffs)
.HasColumnName("list_handler_max_handoffs").IsRequired().HasDefaultValue(4);
builder.HasData(new AppSettingsEntity { Id = AppSettingsEntity.SingletonId });
}
}