Skip to content

Refactor SecretAttachment API to use Laravel Resources and Form Requests #180

@kevalyq

Description

@kevalyq

This issue tracks refactoring improvements for the SecretAttachment API endpoints, as deferred from PR #177 to maintain "One PR = One Topic" principle.

Copilot Review Comments to Address

From PR #177 (6 comments deferred):

  1. Thread PRRT_kwDOQJgcLc5iPRK2 (store method): Use API Resources instead of manual JSON array building
  2. Thread PRRT_kwDOQJgcLc5iPRKm (index method): Use API Resources for consistent response structure
  3. Thread PRRT_kwDOQJgcLc5iPRLg (store validation): Move validation rules to Form Request class
  4. Thread PRRT_kwDOQJgcLc5iPRLc (download accessor): Use property accessor pattern instead of getter method
  5. Thread PRRT_kwDOQJgcLc5iPRKv (named routes): Add route names for better maintainability NOT IMPLEMENTED
  6. Thread PRRT_kwDOQJgcLc5iPRKf (route() helper): Use route() instead of url() NOT IMPLEMENTED

Architecture Decision: Named Routes

Decision: NOT implementing named routes (items 5-6 above).

Rationale:

  • Project uses OpenAPI contracts (/contracts/docs/openapi.yaml) - contract-first architecture
  • Contracts define exact URL paths (e.g., /v1/attachments/{id}/download)
  • Frontend consumes these contract paths directly
  • Named routes are a Laravel backend abstraction that doesn't align with contract-first design
  • Zero named routes exist in 20+ existing routes in routes/api.php
  • All URL generation consistently uses url() helper, not route()

This architectural pattern ensures URLs match OpenAPI specifications exactly, maintaining contract integrity.

Implementation Tasks

  • Create SecretAttachmentResource for JSON transformation
  • Create StoreSecretAttachmentRequest for validation
  • Update controller to use Resource and Form Request
  • Fix property accessor usage (filename_plain vs getter)
  • Add PHPStan type hints for Level Max compliance
  • Add comprehensive test coverage
  • Consolidate test helpers in tests/Pest.php

Completed Work

PR #181: #181

Changes Implemented

  1. API Resource (SecretAttachmentResource):

    • Consistent JSON transformation for attachments
    • ISO 8601 date formatting
    • Filename decryption via accessor
    • Used in store() and index() endpoints
  2. Form Request (StoreSecretAttachmentRequest):

    • Centralized validation rules
    • Config-based file size/type validation
    • Fixed byte-to-KB conversion bug
    • Custom error messages
  3. Controller Refactoring:

    • Removed inline validation
    • Removed manual JSON array building
    • Uses property accessor pattern
  4. Test Coverage:

    • 4 Resource transformation tests
    • 7 Form Request validation tests
    • Helper functions moved to tests/Pest.php
    • All 342 tests passing (1085 assertions)
  5. Quality Gates:

    • PHPStan Level Max: PASSING (fixed 12 type errors)
    • Laravel Pint: PASSING (PSR-12 compliant)
    • REUSE 3.3: Compliant

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status

    ✅ Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions