{"id":45462565,"url":"https://github.com/agash/goaffpro.client","last_synced_at":"2026-02-25T11:01:01.767Z","repository":{"id":339176410,"uuid":"1160777887","full_name":"Agash/GoAffPro.Client","owner":"Agash","description":"Strongly typed .NET client for GoAffPro with build-time generated API clients, resilient HTTP policies, and polling/   event-based feed detection.","archived":false,"fork":false,"pushed_at":"2026-02-22T07:54:33.000Z","size":120,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-02-22T13:02:34.131Z","etag":null,"topics":["api-client","async-stream","csharp","dotnet","event-driven","goaffpro","nswag","nuget","polly"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Agash.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":["Agash"]}},"created_at":"2026-02-18T11:07:43.000Z","updated_at":"2026-02-22T07:54:36.000Z","dependencies_parsed_at":"2026-02-23T09:00:52.491Z","dependency_job_id":null,"html_url":"https://github.com/Agash/GoAffPro.Client","commit_stats":null,"previous_names":["agash/goaffpro.client"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/Agash/GoAffPro.Client","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Agash%2FGoAffPro.Client","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Agash%2FGoAffPro.Client/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Agash%2FGoAffPro.Client/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Agash%2FGoAffPro.Client/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Agash","download_url":"https://codeload.github.com/Agash/GoAffPro.Client/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Agash%2FGoAffPro.Client/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29740714,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-23T07:44:07.782Z","status":"ssl_error","status_checked_at":"2026-02-23T07:44:07.432Z","response_time":90,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api-client","async-stream","csharp","dotnet","event-driven","goaffpro","nswag","nuget","polly"],"created_at":"2026-02-22T08:19:06.171Z","updated_at":"2026-02-23T09:01:07.766Z","avatar_url":"https://github.com/Agash.png","language":"C#","funding_links":["https://github.com/sponsors/Agash"],"categories":[],"sub_categories":[],"readme":"# GoAffPro.Client\n\nAsync-first .NET client for the GoAffPro API with build-time NSwag generation and polling/event-based change detection.\n\n## Targets\n\n- `net8.0`\n- `net10.0` (working on native-AOT compatibility)\n\n## Install\n\n```bash\ndotnet add package GoAffPro.Client\n```\n\n## Quick Start\n\n```csharp\nusing GoAffPro.Client;\n\n// Option 1: create from existing token\nawait using var client = new GoAffProClient(new GoAffProClientOptions\n{\n    BearerToken = \"your-access-token\",\n});\n\n// Option 2: login and create\nawait using var loggedInClient = await GoAffProClient.CreateLoggedInAsync(\n    email: \"affiliate@example.com\",\n    password: \"password123\");\n```\n\n### Wrapper Methods (DX Layer)\n\nThe wrapper methods are built on top of generated clients:\n\n```csharp\n// Fetch orders with optional time filtering\nvar orders = await client.GetOrdersAsync(from: DateTimeOffset.UtcNow.AddDays(-1), limit: 50);\n\n// Fetch affiliates with time range\nvar affiliates = await client.GetAffiliatesAsync(from: startDate, toDate: endDate, limit: 50);\n\n// Fetch payouts and products\nvar payouts = await client.GetPayoutsAsync(limit: 50);\nvar products = await client.GetProductsAsync(limit: 50);\n```\n\nWrapper methods return typed models:\n\n- `GoAffProOrder` (includes Subtotal, AffiliateId, Status)\n- `GoAffProAffiliate` (includes FirstName, LastName, Phone, Country, GroupId)\n- `GoAffProReward` (includes AffiliateId, Type, Metadata, Level, Status) - currently disabled\n- `GoAffProPayout`\n- `GoAffProProduct`\n\nEach model includes strongly typed fields and `RawPayload` (`JsonElement`) for advanced scenarios.\n\n`GetRewardsAsync` is currently disabled because `/user/feed/rewards` is returning `404` (observed on 2026-02-18). The method is marked `[Obsolete]` and returns an empty collection.\n\n### Access Generated Clients Directly\n\n```csharp\nvar loginResponse = await client.User.UserLoginAsync(new GoAffPro.Client.Generated.User.Body\n{\n    Email = \"affiliate@example.com\",\n    Password = \"password123\",\n});\n\nvar publicSites = await client.PublicApi.PublicSitesAsync(\n    site_ids: null,\n    currency: null,\n    keyword: null,\n    limit: 20,\n    offset: 0);\n```\n\n## Event Detection\n\n`GoAffProEventDetector` supports both async streams and classic `.NET` events. It uses time-based filtering to fetch only new items since the last poll.\n\n### Async Streams\n\n```csharp\nusing GoAffPro.Client.Events;\n\nvar detector = new GoAffProEventDetector(client, pollingInterval: TimeSpan.FromSeconds(30));\n\n// Optional: backfill historical data from a specific time\ndetector.OrderStartTime = DateTimeOffset.UtcNow.AddDays(-7);\n\nawait foreach (var order in detector.NewOrdersAsync(cancellationToken))\n{\n    Console.WriteLine($\"New order: {order.Id}\");\n}\n```\n\n### Event Handlers\n\n```csharp\nusing GoAffPro.Client.Events;\n\nvar detector = new GoAffProEventDetector(client, pollingInterval: TimeSpan.FromSeconds(30));\n\ndetector.OrderDetected += (_, args) =\u003e Console.WriteLine($\"Order: {args.Order.Id}\");\ndetector.AffiliateDetected += (_, args) =\u003e Console.WriteLine($\"Affiliate: {args.Affiliate.Id}\");\n\nawait detector.StartAsync(cancellationToken);\n```\n\nThe detector stores the last poll timestamp internally. Use `OrderStartTime` and `AffiliateStartTime` properties to backfill historical data on first run.\n\n## Dependency Injection\n\n```csharp\nservices.AddGoAffProClient(options =\u003e\n{\n    options.BaseUrl = new Uri(\"https://api.goaffpro.com/v1/\", UriKind.Absolute);\n    options.BearerToken = configuration[\"GoAffPro:Token\"];\n    options.Timeout = TimeSpan.FromSeconds(30);\n});\n```\n\n## Example App\n\nAn executable sample is included at:\n\n- `examples/GoAffPro.Client.Example`\n\nRun it with:\n\n```bash\ndotnet run --project examples/GoAffPro.Client.Example\n```\n\n## Build-Time Generation\n\nOn build, `GoAffPro.Client.Generator`:\n\n1. Fetches `https://api.goaffpro.com/docs/admin/swagger-ui-init.js`\n   (or uses `openapi/swagger-ui-init.js` only if you provide a local override file)\n2. Extracts OpenAPI JSON\n3. Filters to `/user/*` and `/public/*`\n4. Normalizes schema gaps for generation\n5. Generates:\n   - `src/GoAffPro.Client/Generated/GoAffProUserClient.g.cs`\n   - `src/GoAffPro.Client/Generated/GoAffProPublicClient.g.cs`\n\nDo not edit `*.g.cs` manually.\n\n## Testing\n\n```bash\ndotnet test\n```\n\n### Integration Tests\n\n```bash\n$env:GOAFFPRO_TEST_TOKEN=\"your-token\"\ndotnet test --filter \"Category=Integration\"\n```\n\n### Contract Snapshot Test\n\nThe test suite validates generated client method signatures against:\n\n- `tests/GoAffPro.Client.Tests/Snapshots/GeneratedClientSignatures.snapshot`\n\nIf generated signatures change, update the snapshot intentionally in the same change.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fagash%2Fgoaffpro.client","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fagash%2Fgoaffpro.client","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fagash%2Fgoaffpro.client/lists"}