|
| 1 | +You are working on `procoders/astrology-api-php` — a PHP 8.1+ SDK for the Astrology API v3. |
| 2 | + |
| 3 | +# Stack |
| 4 | +- PHP 8.1+ with `declare(strict_types=1)` in every file |
| 5 | +- Guzzle 7 for HTTP |
| 6 | +- PHPUnit 10 for testing |
| 7 | +- PHP-CS-Fixer (PSR-12 + single quotes + short arrays + strict params) |
| 8 | + |
| 9 | +# Architecture |
| 10 | +Entry point: `src/AstrologyClient.php` — creates Guzzle client with middleware (retry, API key, logging) and 26 readonly category client properties. |
| 11 | + |
| 12 | +Data flow: CategoryClient method → Validators::validate*() → $this->http->post() → GuzzleHttpHelper → Guzzle → API |
| 13 | + |
| 14 | +Key files: |
| 15 | +- `src/Categories/BaseCategoryClient.php` — abstract base with `buildUrl(string ...$segments)` |
| 16 | +- `src/Utils/HttpHelper.php` — interface: get/post/put/delete |
| 17 | +- `src/Utils/GuzzleHttpHelper.php` — extracts `data` or `result` from JSON responses |
| 18 | +- `src/Utils/Validators.php` — all static validation, throws `AstrologyError` |
| 19 | +- `src/Exceptions/AstrologyError.php` — single exception type with statusCode, errorCode, details |
| 20 | +- `src/Categories/InsightsClient.php` — special: contains 5 nested sub-clients |
| 21 | + |
| 22 | +# Strict Rules |
| 23 | +1. Every class is `final` unless it needs inheritance |
| 24 | +2. Use `readonly` properties for immutable state |
| 25 | +3. Category client methods return `mixed`, take `array $options = []` as last param |
| 26 | +4. Validate BEFORE HTTP calls, never after |
| 27 | +5. Only throw `AstrologyError` — never other exception types |
| 28 | +6. Validation context strings: `'ClassName.fieldName'` format |
| 29 | +7. `buildUrl()` accepts only strings — cast integers: `(string) $year` |
| 30 | + |
| 31 | +# New Category Client Pattern |
| 32 | +```php |
| 33 | +<?php |
| 34 | +declare(strict_types=1); |
| 35 | +namespace Procoders\AstrologyApi\Categories; |
| 36 | +use Procoders\AstrologyApi\Utils\HttpHelper; |
| 37 | +use Procoders\AstrologyApi\Utils\Validators; |
| 38 | + |
| 39 | +final class FooClient extends BaseCategoryClient |
| 40 | +{ |
| 41 | + private const API_PREFIX = '/api/v3/foo'; |
| 42 | + public function __construct(HttpHelper $http) { parent::__construct($http, self::API_PREFIX); } |
| 43 | + |
| 44 | + public function getBar(array $request, array $options = []): mixed |
| 45 | + { |
| 46 | + Validators::validateSubject($request['subject'] ?? [], 'BarRequest.subject'); |
| 47 | + return $this->http->post($this->buildUrl('bar'), $request, $options); |
| 48 | + } |
| 49 | +} |
| 50 | +``` |
| 51 | +Then register in AstrologyClient.php: add use import, readonly property, constructor instantiation. |
| 52 | + |
| 53 | +# Unit Test Pattern |
| 54 | +Use `SpyHttpHelper` (captures lastMethod, lastPath, lastPayload, lastQuery, lastOptions): |
| 55 | +```php |
| 56 | +$this->http = new SpyHttpHelper(); |
| 57 | +$this->client = new FooClient($this->http); |
| 58 | +$this->client->getBar(['subject' => $this->subject()]); |
| 59 | +self::assertSame('/api/v3/foo/bar', $this->http->lastPath); |
| 60 | +``` |
| 61 | + |
| 62 | +# Integration Test Pattern |
| 63 | +Extend `IntegrationTestCase` — auto-skips without `ASTROLOGY_API_KEY` env var: |
| 64 | +```php |
| 65 | +$response = self::$client->foo->getBar(['subject' => $this->subject()]); |
| 66 | +$this->assertSuccessResponse($response); |
| 67 | +``` |
| 68 | +Real API needs location inside `birth_data`: latitude, longitude, city, nation, timezone. |
| 69 | + |
| 70 | +# Validation Reference |
| 71 | +Subject: birth_data with year(1900-2100), month(1-12), day(1-31), hour(0-23), minute(0-59), second(0-59) |
| 72 | +Sun signs: Aries..Pisces + Ari,Tau,Gem,Can,Vir,Lib,Sco,Sag,Cap,Aqu,Pis |
| 73 | +Horoscope formats: paragraph, bullets, short, long |
| 74 | +Progression types: secondary, primary, tertiary, minor |
| 75 | +Direction types: solar_arc, symbolic, profection, naibod |
| 76 | +House systems: P, W, K, A, R, C, B, M, O, E, V, X, H, T, G |
| 77 | + |
| 78 | +# Commands |
| 79 | +``` |
| 80 | +composer test # all tests |
| 81 | +composer test:unit # mocked unit tests |
| 82 | +composer test:integration # real API (needs ASTROLOGY_API_KEY) |
| 83 | +composer lint # check style |
| 84 | +composer lint:fix # auto-fix |
| 85 | +``` |
| 86 | + |
| 87 | +# Pitfalls |
| 88 | +- SVG/PDF endpoints return non-JSON — don't assume array |
| 89 | +- InsightsClient has nested sub-clients: $client->insights->relationship->getCompatibility(...) |
| 90 | +- Use caret constraints (^7.5) not exact versions — this is a library |
0 commit comments