diff --git a/.gitignore b/.gitignore index add57be..b63c7f9 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,6 @@ bin/ obj/ /packages/ riderModule.iml -/_ReSharper.Caches/ \ No newline at end of file +/_ReSharper.Caches/ +.idea/.idea.GymLogAI/.idea/indexLayout.xml +.idea/.idea.GymLogAI/.idea/vcs.xml diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..4df6db8 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,50 @@ +# AGENTS.md + +Shared rules for all AI agents working in this repository. + +## Tech Stack + +- **.NET 10.0** — ASP.NET Core minimal APIs +- **C#** — primary language +- **Docker / Docker Compose** — containerization + +## Commands + +```bash +# Build +dotnet build + +# Run (development) +dotnet run --project GymLogAI.API/ + +# Run with HTTPS profile +dotnet run --project GymLogAI.API/ --launch-profile https + +# Docker Compose +docker compose -f compose.yaml up --build +``` + +No test project exists yet. When one is added, the command will be `dotnet test`. + +## Project Structure + +``` +GymLogAI.sln +GymLogAI.API/ + Program.cs # entry point, minimal API endpoint registration + appsettings*.json # environment-specific config + Dockerfile # multi-stage build (SDK 10 → Runtime 10) +compose.yaml # Docker Compose orchestration +``` + +## Architecture + +- Minimal API pattern — endpoints registered directly in `Program.cs` +- Ports: HTTP 5202 (local), HTTPS 7225 (local); 8080/8081 inside Docker +- OpenAPI enabled via `Microsoft.AspNetCore.OpenApi` + +## Conventions + +- Keep endpoints in `Program.cs` until the project grows enough to warrant endpoint groups or controllers +- Use records for DTOs +- Follow existing `appsettings.json` / `appsettings.Development.json` split for environment config diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..b94f862 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,11 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +> All shared rules (commands, architecture, conventions) live in [AGENTS.md](AGENTS.md) and apply here as well. + +## Claude Code–Specific Notes + +- This is a greenfield project — the `WeatherForecast` endpoint in `Program.cs` is a template placeholder and can be replaced entirely. +- There is no database, auth, or domain layer yet; add these incrementally as features are defined. +- REST Client test file: `GymLogAI.API/GymLogAI.API.http` — keep it updated when endpoints change. diff --git a/GymLogAI.API/GymLogAI.API.csproj b/GymLogAI.API/GymLogAI.API.csproj index 4958600..85bd4c4 100644 --- a/GymLogAI.API/GymLogAI.API.csproj +++ b/GymLogAI.API/GymLogAI.API.csproj @@ -8,7 +8,7 @@ - + @@ -17,4 +17,8 @@ + + + + diff --git a/GymLogAI.API/Program.cs b/GymLogAI.API/Program.cs index e1c66f6..e49e0e6 100644 --- a/GymLogAI.API/Program.cs +++ b/GymLogAI.API/Program.cs @@ -1,3 +1,5 @@ +using GymLogAI.TgBot; + namespace GymLogAI.API; public class Program @@ -8,6 +10,7 @@ public class Program // Add services to the container. builder.Services.AddAuthorization(); + builder.Services.AddTgBot(builder.Configuration); // Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi builder.Services.AddOpenApi(); @@ -45,4 +48,4 @@ public class Program app.Run(); } -} \ No newline at end of file +} diff --git a/GymLogAI.API/appsettings.Development.json b/GymLogAI.API/appsettings.Development.json index 0c208ae..8d4f7b7 100644 --- a/GymLogAI.API/appsettings.Development.json +++ b/GymLogAI.API/appsettings.Development.json @@ -4,5 +4,8 @@ "Default": "Information", "Microsoft.AspNetCore": "Warning" } + }, + "TelegramBot": { + "BotToken": "" } } diff --git a/GymLogAI.API/appsettings.json b/GymLogAI.API/appsettings.json index 10f68b8..7afdb19 100644 --- a/GymLogAI.API/appsettings.json +++ b/GymLogAI.API/appsettings.json @@ -5,5 +5,8 @@ "Microsoft.AspNetCore": "Warning" } }, + "TelegramBot": { + "BotToken": "" + }, "AllowedHosts": "*" } diff --git a/GymLogAI.TgBot/GymLogAI.TgBot.csproj b/GymLogAI.TgBot/GymLogAI.TgBot.csproj new file mode 100644 index 0000000..418d4b4 --- /dev/null +++ b/GymLogAI.TgBot/GymLogAI.TgBot.csproj @@ -0,0 +1,13 @@ + + + + net10.0 + enable + enable + + + + + + + diff --git a/GymLogAI.TgBot/TelegramBotOptions.cs b/GymLogAI.TgBot/TelegramBotOptions.cs new file mode 100644 index 0000000..c737dd5 --- /dev/null +++ b/GymLogAI.TgBot/TelegramBotOptions.cs @@ -0,0 +1,8 @@ +namespace GymLogAI.TgBot; + +public sealed record TelegramBotOptions +{ + public const string SectionName = "TelegramBot"; + + public string? BotToken { get; init; } +} diff --git a/GymLogAI.TgBot/TgBotServiceCollectionExtensions.cs b/GymLogAI.TgBot/TgBotServiceCollectionExtensions.cs new file mode 100644 index 0000000..509a339 --- /dev/null +++ b/GymLogAI.TgBot/TgBotServiceCollectionExtensions.cs @@ -0,0 +1,19 @@ +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; + +namespace GymLogAI.TgBot; + +public static class TgBotServiceCollectionExtensions +{ + public static IServiceCollection AddTgBot(this IServiceCollection services, IConfiguration configuration) + { + ArgumentNullException.ThrowIfNull(services); + ArgumentNullException.ThrowIfNull(configuration); + + services + .AddOptions() + .Bind(configuration.GetSection(TelegramBotOptions.SectionName)); + + return services; + } +} diff --git a/GymLogAI.sln b/GymLogAI.sln index f881c31..48be9c8 100644 --- a/GymLogAI.sln +++ b/GymLogAI.sln @@ -7,6 +7,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution compose.yaml = compose.yaml EndProjectSection EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GymLogAI.TgBot", "GymLogAI.TgBot\GymLogAI.TgBot.csproj", "{BAF381C4-F522-4A59-B86D-3B9D3DA3D6AD}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -17,5 +19,9 @@ Global {42540161-196B-43B8-998E-FA9BDD01A74C}.Debug|Any CPU.Build.0 = Debug|Any CPU {42540161-196B-43B8-998E-FA9BDD01A74C}.Release|Any CPU.ActiveCfg = Release|Any CPU {42540161-196B-43B8-998E-FA9BDD01A74C}.Release|Any CPU.Build.0 = Release|Any CPU + {BAF381C4-F522-4A59-B86D-3B9D3DA3D6AD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BAF381C4-F522-4A59-B86D-3B9D3DA3D6AD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BAF381C4-F522-4A59-B86D-3B9D3DA3D6AD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BAF381C4-F522-4A59-B86D-3B9D3DA3D6AD}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection EndGlobal