Compare commits

..

No commits in common. "main" and "0.7.42" have entirely different histories.
main ... 0.7.42

7 changed files with 34 additions and 245 deletions

243
CLAUDE.md
View File

@ -27,39 +27,28 @@ The services follow a message bus pattern using RabbitMQ for async communication
**Note:** WTelegram sends both `UpdateNewChannelMessage` and `UpdateEditChannelMessage` for the same message. TelegramListener publishes separate events to avoid duplicate notifications downstream.
Each service follows Clean Architecture with separate projects for:
- **Host** (API/entry point) - ASP.NET Core application, controllers, startup configuration
- **AppServices** (business logic) - Use cases, business logic, command/query handlers
- **Core** (shared utilities) - Domain entities, interfaces, shared logic
- **Api.Contracts** (REST API contracts) - DTOs, request/response models for REST endpoints (published as NuGet)
- **Async.Api.Contracts** (event contracts) - Event DTOs for RabbitMQ messaging (published as NuGet)
- **Persistence** (database layer) - EF Core DbContext, repositories, data access (text-matcher, users only)
- **Migrator** (database migrations) - EF Core migrations, migration scripts (text-matcher, users only)
**Project Structure Examples:**
- telegram-listener: Host, AppServices, Core, Async.Api.Contracts (no database)
- telegram-client: Host, AppServices, Core (no database, no published contracts)
- text-matcher: Host, AppServices, Core, Api.Contracts, Async.Api.Contracts, Persistence, Migrator
- users: Host, AppServices, Core, Api.Contracts, Persistence, Migrator
- Host (API/entry point)
- AppServices (business logic)
- Core (shared utilities)
- Api.Contracts (REST API contracts)
- Async.Api.Contracts (event contracts)
- Persistence (database layer, where applicable)
- Migrator (database migrations, where applicable)
## Development Commands
### Running the System
```bash
# IMPORTANT: Before building with Docker Compose, prepare the build environment
./prepare-build.sh
# Start all services with Docker Compose
docker-compose up
# Start individual services for development (no preparation needed)
# Start individual services for development
cd telegram-client && dotnet run --project src/Nocr.TelegramClient.Host
cd telegram-listener && dotnet run --project src/Nocr.TelegramListener.Host
cd telegram-listener && dotnet run --project src/Nocr.TelegramListener.Host
cd text-matcher && dotnet run --project src/Nocr.TextMatcher.Host
cd users && dotnet run --project src/Nocr.Users.Host
```
**Note:** The `prepare-build.sh` script copies `nuget.config` to all submodule roots, which is required for Docker builds. This step is automatic in CI/CD but must be run manually for local Docker Compose builds.
### Building
```bash
# Build individual services
@ -71,17 +60,8 @@ dotnet build src/Nocr.<ServiceName>.Host
### Testing
```bash
# Run all tests in text-matcher
# Run unit tests (only text-matcher has tests currently)
cd text-matcher && dotnet test
# Run tests for a specific project
cd text-matcher && dotnet test tests/Nocr.TextMatcher.AppServices.UnitTests/Nocr.TextMatcher.AppServices.UnitTests.csproj
# Run tests with verbose output
cd text-matcher && dotnet test --verbosity detailed
# Run tests with code coverage (if configured)
cd text-matcher && dotnet test --collect:"XPlat Code Coverage"
```
### Database Migrations
@ -95,29 +75,6 @@ cd users && ./src/Nocr.Users.Migrator/AddMigration.sh MyMigrationName
# Apply migrations (handled automatically by migrator containers in docker-compose)
```
### Working with Git Submodules
```bash
# Initialize submodules after cloning the repository
git submodule update --init --recursive
# Update all submodules to their latest commits on main
./update-submodules.sh
# Commit and push changes to all submodules at once
./commit-all.sh "Your commit message"
# Update a single submodule
cd telegram-listener
git pull origin main
cd ..
git add telegram-listener
git commit -m "Update telegram-listener submodule"
# Check status of all submodules
git submodule status
```
## Configuration
**📖 See [CONFIGURATION.md](CONFIGURATION.md) for detailed configuration guide.**
@ -176,16 +133,13 @@ When running with docker-compose:
## Key Technologies
- **.NET 8** - All services built on .NET 8
- **ASP.NET Core Web APIs** - REST endpoints and hosting
- **Entity Framework Core with MariaDB** - ORM for text-matcher and users databases
- **WTelegramClient** - MTProto API client for telegram-listener
- **Telegram.Bot** - Bot API client for telegram-client
- **Rebus** - Message bus abstraction over RabbitMQ
- **RabbitMQ** - Message broker for async event-driven communication
- **Docker & Docker Compose** - Local development and containerization
- **Kaniko** - Container image building in CI/CD
- **Drone CI** - CI/CD pipeline on Kubernetes
- .NET 8
- ASP.NET Core Web APIs
- Entity Framework Core with MariaDB
- WTelegramClient for Telegram API
- Rebus for message bus (RabbitMQ)
- Docker & Docker Compose for containerization
- Drone CI/CD on Kubernetes
## NuGet Package Management
@ -326,88 +280,6 @@ git push && git push --tags
- Deploys specified tag's images (or `latest`)
- Duration: ~1 minute
## Development Workflows
### Making Changes to a Single Service
When working on a specific service (e.g., telegram-listener):
```bash
# 1. Navigate to the submodule
cd telegram-listener
# 2. Create a feature branch in the submodule
git checkout -b feature/new-feature
# 3. Make your changes to the code
# ... edit files ...
# 4. Test locally (if tests exist)
dotnet test
# 5. Commit and push in the submodule
git add .
git commit -m "Add new feature"
git push origin feature/new-feature
# 6. Return to parent repo and update submodule reference
cd ..
git add telegram-listener
git commit -m "Update telegram-listener: Add new feature"
git push origin main
```
### Updating Contract Packages
When you change event contracts (Async.Api.Contracts) or REST contracts (Api.Contracts):
```bash
# 1. Make changes to contracts in the submodule
cd text-matcher
# ... edit Nocr.TextMatcher.Async.Api.Contracts ...
git add . && git commit -m "Add new event contract"
git push origin main
# 2. Return to parent repo and publish contracts only
cd ..
git add text-matcher
git commit -m "contracts_only:text_matcher - Add new event contract"
git tag 0.8.6
git push && git push --tags
# 3. Other services can now reference the new contract version
# Update their .csproj or Directory.Packages.props to use version 0.8.6
```
### Working Across Multiple Services
When implementing a feature that spans multiple services:
```bash
# 1. Update each submodule in sequence
cd telegram-listener
git checkout -b feature/cross-service-feature
# ... make changes ...
git commit -m "Part 1: Update listener"
git push origin feature/cross-service-feature
cd ../text-matcher
git checkout -b feature/cross-service-feature
# ... make changes ...
git commit -m "Part 2: Update matcher"
git push origin feature/cross-service-feature
# 2. Update parent repo to reference all changes
cd ..
git add telegram-listener text-matcher
git commit -m "Implement cross-service feature"
git push origin main
# 3. Tag for full release
git tag v1.5.0
git push --tags
```
## Common CI/CD Workflows
### Test a Feature Branch
@ -473,83 +345,4 @@ Located in `_deploy/scripts/`:
- **Parallel execution** for independent operations
- **Proper dependency order**: Contracts → Images → Deploy
- **Kaniko layer caching** for faster Docker builds
- **Docker-in-Docker** support for Testcontainers in tests
## Troubleshooting
### Submodule Issues
**Problem:** Submodule directories are empty after cloning
```bash
# Solution: Initialize submodules
git submodule update --init --recursive
```
**Problem:** Submodule is in detached HEAD state
```bash
# Solution: Check out the main branch in the submodule
cd <submodule-name>
git checkout main
git pull origin main
cd ..
```
**Problem:** Changes in submodule not reflected in parent repo
```bash
# Solution: Update submodule reference in parent
cd .. # Return to parent repo
git add <submodule-name>
git commit -m "Update <submodule-name> reference"
```
### Build Issues
**Problem:** NuGet package restore fails with NU1507 warning
```bash
# Solution: Copy nuget.config to submodule root
cp nuget.config telegram-listener/
cd telegram-listener && dotnet restore
```
**Problem:** Cannot find Nocr.* contract packages
```bash
# Solution: Ensure you have access to the private NuGet feed
# Check nuget.config has the correct source configuration
# Verify credentials for the "musk" package source
```
### Docker Compose Issues
**Problem:** Service cannot connect to RabbitMQ
```bash
# Solution: Use the Docker network hostname, not localhost
# In docker-compose environment: nocr-rabbitmq:5672
# In local development: localhost:5672
```
**Problem:** Database connection fails
```bash
# Solution: Wait for database health checks to pass
# Check docker-compose logs for database container
docker-compose logs nocr-text-matcher-db
# Database takes 10-30 seconds to be ready on first start
```
### CI/CD Issues
**Problem:** Pipeline doesn't trigger on tag
```bash
# Solution: Ensure tag matches expected patterns
# Feature validation: feature/*, fix/*, issues/*
# Main validation: main branch
# Contracts: Tag with commit message containing "contracts_only:<service>"
# Full release: Any tag without special markers
# Deploy-only: Tag with commit message containing "deploy_only:"
```
**Problem:** Docker image build fails in Kaniko
```bash
# Solution: Check if nuget.config is correctly copied
# Verify _deploy/deploy.sh contains nuget.config copy step
# Check Drone logs for nuget.config presence in build context
```
- **Docker-in-Docker** support for Testcontainers in tests

View File

@ -5,6 +5,8 @@ services:
build:
context: telegram-client
dockerfile: src/Nocr.TelegramClient.Host/Dockerfile
additional_contexts:
rootconfig: .
ports:
- 5050:8080
# IMPORTANT: Create .nocr.env file in project root with your secrets
@ -29,6 +31,8 @@ services:
build:
context: telegram-listener
dockerfile: src/Nocr.TelegramListener.Host/Dockerfile
additional_contexts:
rootconfig: .
ports:
- 5040:8080
# IMPORTANT: Create .nocr.env file in project root with your secrets
@ -55,6 +59,8 @@ services:
build:
context: text-matcher
dockerfile: src/Nocr.TextMatcher.Host/Dockerfile
additional_contexts:
rootconfig: .
ports:
- 5041:8080
# IMPORTANT: Create .nocr.env file in project root with your secrets
@ -80,6 +86,8 @@ services:
build:
context: text-matcher
dockerfile: src/Nocr.TextMatcher.Migrator/Dockerfile
additional_contexts:
rootconfig: .
image: nocr-text-matcher-migrations:latest
container_name: nocr-text-matcher-migrator
environment:
@ -94,6 +102,8 @@ services:
build:
context: users
dockerfile: src/Nocr.Users.Host/Dockerfile
additional_contexts:
rootconfig: .
ports:
- 5042:8080
# IMPORTANT: Create .nocr.env file in project root with your secrets
@ -117,6 +127,8 @@ services:
build:
context: users
dockerfile: src/Nocr.Users.Migrator/Dockerfile
additional_contexts:
rootconfig: .
image: nocr-users-migrator:latest
container_name: nocr-users-migrator
environment:

View File

@ -1,16 +0,0 @@
#!/bin/bash
# Prepares the build environment by copying nuget.config to all submodules
# This is required for both local docker-compose builds and CI/CD
set -e
echo "📦 Copying nuget.config to all submodules..."
for submodule in telegram-client telegram-listener text-matcher users; do
if [ -d "$submodule" ]; then
cp nuget.config "$submodule/"
echo "✓ Copied to $submodule/"
fi
done
echo "✅ Build preparation complete!"

@ -1 +1 @@
Subproject commit e8ee01cbe809867305ff02611155cddffccbb401
Subproject commit c6f9c92eac786b47eaf0c6c5109fd216731648e0

@ -1 +1 @@
Subproject commit 9ad504753550414edd96ef4194a3e0ee7e604e28
Subproject commit a31068d63e9c12d87fa04399c7bdbb2938390eea

@ -1 +1 @@
Subproject commit 1a55061e4b1b125d1b911f479fc830fb94cd93cc
Subproject commit 3cf29a5aa1a54879c54200cb358c5bdbf41847f4

2
users

@ -1 +1 @@
Subproject commit 30ae0c043ca2f8958223d6fb343b8b3e3561d727
Subproject commit f692e329256d022377adaccbc72c53b393f2a29f