# Service Class Guidelines & Flow: ConnectionProviderService This document outlines the architectural flow, design patterns, and coding guidelines implemented within the ConnectionProviderService class. It serves as a reference for maintaining this service and acts as a blueprint for creating similar service classes within the application. ## 1. General Coding Guidelines The service class adheres to several strict Laravel and general PHP best practices to ensure robustness, predictability, and maintainability. 1. Strict Typing: The file declares strict_types=1 at the top. All method arguments and return values must have explicit type hints. 2. Data Transfer Objects (DTOs): Instead of passing raw arrays or generic Laravel Request objects, the service utilizes strongly typed DTOs (via Spatie\LaravelData). Input: StoreConnectionProviderRequestData Output: ConnectionProviderData, PaginatedDataCollection 3. Database Transactions: All data mutation methods (Create, Update, Delete) are wrapped within DB::transaction() closures to guarantee database integrity. If any part of the operation fails, the entire transaction rolls back. 4. The #[NoDiscard] Attribute: Read-only methods (search, getAll, getProvider) utilize the #[NoDiscard] attribute. This strictly enforces that the calling code must capture and use the returned data, preventing logic leaks where a developer calls a getter but ignores the result. 5. Explicit Exception Documentation: Every method that can throw an exception documents it clearly in the PHPDoc block ( e.g., @throws ModelNotFoundException, @throws Throwable). ## 2. Architectural Flow by Operation ### A. Read Operations Read operations are optimized for memory and performance by explicitly selecting only the necessary columns. * search(string $value) Flow: Initiates an Eloquent query targeting the slug or name columns using a LIKE operator (%value%). Returns: An Eloquent Collection of ConnectionProvider models. * getAll() Flow: Queries the database selecting only id, name, and slug. It then paginates the results. Returns: The paginated result is transformed into a PaginatedDataCollection containing ConnectionProviderData objects. * getProvider(string $slug) Flow: Looks up a specific provider by its slug, selecting only id, name, and slug. Returns: Transforms the found model into a single ConnectionProviderData object. ### B. Write Operations (Create / Update) Write operations rely on DTOs to ensure the data being inserted or updated is pre-validated and formatted correctly. * create(StoreConnectionProviderRequestData $data) Flow: Opens a DB transaction. Converts the validated DTO to an array and passes it to the Eloquent create method. * update(string $slug, StoreConnectionProviderRequestData $data) Flow: Opens a DB transaction. Locates the model by its slug and updates it using the array representation of the provided DTO. ### C. Delete Operation (Cascade & Logging) The delete method contains the most complex flow, handling cascading soft-deletes and custom audit logging. delete(string $slug) Step 1 (Find): Locates the ConnectionProvider by slug or throws a ModelNotFoundException. Step 2 (Fetch Relations): Retrieves the id and name of all associated connectedApps to preserve their state for the audit log. Step 3 (Cascade Delete): Performs a mass query deletion ($provider->connectedApps()->delete()). Note: Because this is a mass delete, individual model events for ConnectedApp will not fire. Step 4 (Provider Delete): Disables default logging on the provider to prevent redundant logs, then deletes the provider. Step 5 (Audit Log): Manually triggers a comprehensive Spatie Activity log (provider_cascade_deleted). It records the specific user (:causer.name), the provider details, and an array of the deleted child apps. ## 3. Performance & Security Best Practices When extending this service or building new ones, adhere strictly to the following patterns demonstrated in the code: 1. Selective Querying: Always use ```$model->select(['id', 'column_name'])``` when returning data to the frontend or DTOs to avoid memory bloat from fetching unused columns (e.g., timestamps, hidden credentials). 2. Route/Key Binding vs. Service Lookups: Notice that update, delete, and getProvider accept a primitive string ```$slug / $id``` rather than an already-resolved Model. This keeps the service decoupled from HTTP routing logic and allows it to be called safely from CLI commands or background jobs. 3. Auditable Actions: For destructive actions (like cascades), always disable automatic noise and implement a custom, highly detailed activity log so system administrators can trace exactly what data was removed and by whom.