feat(data,worker): add db schema init and signalr hub skeleton
Data layer: Paths helper with ~/%USERPROFILE% expansion, SqliteConnectionFactory (WAL + foreign keys), SchemaInitializer that applies the embedded schema.sql, and POCO entities for lists/tasks/tags/worktrees. Worker: WorkerConfig loader (~/.todo-app/worker.config.json with defaults), WorkerHub exposing Ping(), and Program.cs wiring Kestrel to 127.0.0.1:<port>, SignalR at /hub, schema applied on startup. Pins Microsoft.Data.Sqlite and Microsoft.Extensions.Hosting to 8.x for net8.0 compatibility. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
31
src/ClaudeDo.Data/Paths.cs
Normal file
31
src/ClaudeDo.Data/Paths.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
namespace ClaudeDo.Data;
|
||||
|
||||
public static class Paths
|
||||
{
|
||||
/// <summary>
|
||||
/// Expands a leading "~" or "%USERPROFILE%" and returns an absolute path.
|
||||
/// Relative paths are resolved against <paramref name="baseDir"/> (default: current directory).
|
||||
/// </summary>
|
||||
public static string Expand(string path, string? baseDir = null)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(path))
|
||||
throw new ArgumentException("Path must not be empty.", nameof(path));
|
||||
|
||||
var expanded = Environment.ExpandEnvironmentVariables(path);
|
||||
|
||||
if (expanded.StartsWith("~", StringComparison.Ordinal))
|
||||
{
|
||||
var home = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
|
||||
expanded = home + expanded[1..];
|
||||
}
|
||||
|
||||
if (!Path.IsPathRooted(expanded))
|
||||
expanded = Path.GetFullPath(expanded, baseDir ?? Environment.CurrentDirectory);
|
||||
|
||||
return Path.GetFullPath(expanded);
|
||||
}
|
||||
|
||||
/// <summary>~/.todo-app — parent directory for db, logs, config, sandbox, worktrees.</summary>
|
||||
public static string AppDataRoot() =>
|
||||
Expand("~/.todo-app");
|
||||
}
|
||||
Reference in New Issue
Block a user