Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Relesys Users Laravel Package

getsno/relesys-users

Laravel 10 (PHP 8.1+) client for the Relesys User Management API. Access endpoints for users, departments, user groups, custom fields and communication with support for filtering, sorting and pagination, plus create/update users and status changes.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the package:
    composer require getsno/relesys-users
    
  2. Configure .env with Relesys credentials:
    RELESYS_CLIENT_ID=your_client_id
    RELESYS_CLIENT_SECRET=your_client_secret
    
  3. First API call (e.g., fetch a user):
    use Getsno\Relesys\Facades\Relesys;
    
    $user = Relesys::users()->getUser('user-uuid-here');
    

First Use Case: User Creation

use Getsno\Relesys\Facades\Relesys;
use Getsno\Relesys\Api\UserManagement\Entities\User;

$user = User::fromArray([
    'name' => 'John Doe',
    'email' => 'john@example.com',
    'primaryDepartmentId' => 'dept-uuid-here',
]);

$createdUser = Relesys::users()->createUser($user);

Where to Look First

  • Facade: Getsno\Relesys\Facades\Relesys (entry point for all endpoints).
  • Entities: Getsno\Relesys\Api\UserManagement\Entities (e.g., User, UserPatch).
  • Enums: Getsno\Relesys\Api\UserManagement\Enums (e.g., UserStatus).
  • Tests: /tests directory for real-world examples (run with composer test).

Implementation Patterns

Core Workflow: CRUD Operations

  1. Create:
    $user = User::fromArray([...]);
    Relesys::users()->createUser($user);
    
  2. Read (with pagination/filtering):
    $queryParams = (new ApiQueryParams())
        ->addFilter('status', UserStatus::Activated->value)
        ->sortBy('name')
        ->limit(10);
    
    $users = Relesys::users()->getUsers($queryParams, page: 1);
    
  3. Update:
    $patch = (new UserPatch())
        ->title('Senior Developer')
        ->birthDate(Carbon::today()->subYears(30));
    
    Relesys::users()->updateUser('user-uuid', $patch);
    
  4. Delete/Status Changes:
    Relesys::users()->changeUserStatus('user-uuid', UserStatus::Disabled);
    

Integration Tips

  • Event Listeners: Attach to user.created, user.updated (if Relesys supports webhooks).
  • Caching: Cache frequent queries (e.g., getUsers) with Laravel’s cache:
    $users = Cache::remember("relesys_users_{$page}", now()->addHours(1), fn() =>
        Relesys::users()->getUsers($queryParams, $page)
    );
    
  • Error Handling: Use try-catch with Getsno\Relesys\Exceptions\RelesysHttpClientException:
    try {
        Relesys::users()->getUser('invalid-uuid');
    } catch (RelesysHttpClientException $e) {
        report($e->failedRequest->toPsrResponse());
    }
    
  • Bulk Operations: Leverage pagination for large datasets:
    $page = 1;
    do {
        $users = Relesys::users()->getUsers($queryParams, $page);
        foreach ($users as $user) { /* ... */ }
        $page++;
    } while ($users->hasMorePages());
    

Advanced Patterns

  • Custom Fields: Dynamically handle schema-less data:
    $user = Relesys::users()->getUser('user-uuid');
    $customFieldValue = $user->customFields?->get('department_role');
    
  • Departments/User Groups: Pre-fetch hierarchies:
    $departments = Relesys::departments()->getDepartments();
    $userGroups = Relesys::userGroups()->getUserGroups();
    
  • Communication: Manage messages/templates:
    $template = Relesys::communication()->getTemplate('welcome-email');
    Relesys::communication()->sendMessage($template, ['user-uuid']);
    

Gotchas and Tips

Pitfalls

  1. Empty Arrays in Custom Fields:

    • Issue: The API rejects empty arrays for customFields. Use null instead:
      $user = User::fromArray([
          'customFields' => null, // Not []
      ]);
      
    • Fix: Check tests/Feature/UserTest.php for edge-case handling.
  2. UUID Validation:

    • Issue: Invalid UUIDs (e.g., strings) may not throw clear errors. Validate client-side:
      if (!Str::isUuid($userId)) {
          throw new \InvalidArgumentException('Invalid UUID format');
      }
      
  3. Pagination Quirks:

    • Issue: hasMorePages() may return true even if the next page is empty. Always check count():
      if ($users->count() === 0) break;
      
  4. Phone Number Formatting:

    • Issue: Ensure countryCode is numeric (not string):
      $phone = [
          'countryCode' => 47, // Not '47'
          'number' => '12345678',
      ];
      
  5. Enum Case Sensitivity:

    • Issue: Enums use camelCase (e.g., UserStatus::Activated), not snake_case:
      // Wrong:
      UserStatus::activated
      // Correct:
      UserStatus::Activated
      

Debugging Tips

  • Enable API Logging: Add to .env:

    RELESYS_LOG_REQUESTS=true
    

    Logs appear in storage/logs/laravel.log.

  • Mock API Calls in Tests: Use the testbench isolation mode (default):

    // tests/Feature/UserTest.php
    public function test_user_creation()
    {
        $this->fake(); // Mocks all API calls
        // ...
    }
    
  • Inspect Raw Responses: Access the underlying HTTP client:

    $response = Relesys::users()->getUser('user-uuid');
    $rawBody = $response->getBody()->getContents();
    

Extension Points

  1. Custom API Clients: Override the default HTTP client by binding a custom Getsno\Relesys\Http\Client in AppServiceProvider:

    $this->app->bind(Getsno\Relesys\Http\Client::class, function ($app) {
        return new CustomHttpClient(
            $app['config']['services.relesys.client_id'],
            $app['config']['services.relesys.client_secret']
        );
    });
    
  2. Entity Extensions: Extend User or UserPatch for domain-specific logic:

    class ExtendedUser extends \Getsno\Relesys\Api\UserManagement\Entities\User
    {
        public function isActiveDeveloper()
        {
            return $this->status === UserStatus::Activated
                && $this->customFields?->get('role') === 'developer';
        }
    }
    
  3. Query Builder Hooks: Intercept ApiQueryParams before API calls:

    $queryParams = (new ApiQueryParams())
        ->addFilter('status', UserStatus::Activated->value)
        ->addCustomFilter('custom', 'value'); // Extend as needed
    

Configuration Quirks

  • Rate Limiting: Relesys may throttle requests. Implement exponential backoff:

    use Symfony\Component\HttpClient\Retry\RetryStrategy;
    
    $client = HttpClient::create([
        'base_uri' => 'https://api.relesysapp.net',
        'auth_bearer' => $token,
        'retry' => [
            'max_retries' => 3,
            'delay' => 1000, // ms
            'multiplier' => 2,
            'max_delay' => 5000,
        ],
    ]);
    
  • Timezone Handling: Ensure Carbon instances match Relesys’s expected timezone (default: UTC):

    $patch = (new UserPatch())
        ->birthDate(Carbon::parse('1990-01-01')->setTimezone('UTC'));
    
  • Environment Variables: Use config('services.relesys') for credentials (not .env directly):

    config([
        'services.relesys' => [
            'client_id' => env('RELESYS_CLIENT_ID'),
            'client_secret' => env('RELESYS_CLIENT_SECRET'),
        ],
    ]);
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor