## ADDED Requirements ### Requirement: Accept AT Protocol identifier as URL path segment The system SHALL expose a single HTTP route `GET /{identifier}` where `{identifier}` is either an AT Protocol handle or a DID. The identifier SHALL be extracted from the first path segment and passed to the resolution pipeline. All requests SHALL pass through request logging middleware before reaching the handler. #### Scenario: Handle in path - **WHEN** a request arrives at `GET /alice.bsky.social` - **THEN** the system SHALL treat `alice.bsky.social` as the identifier #### Scenario: DID in path - **WHEN** a request arrives at `GET /did:plc:abc123` - **THEN** the system SHALL treat `did:plc:abc123` as the identifier #### Scenario: Request is logged - **WHEN** any request arrives at the handler - **THEN** the system SHALL emit a log line via the request logging middleware after the response is sent --- ### Requirement: Accept image transform parameters via query string The system SHALL accept the following optional query parameters and pass them to the image transform pipeline: | Parameter | Type | Description | |---|---|---| | `w` | integer | Output width in pixels | | `h` | integer | Output height in pixels | | `q` | integer (1–100) | Output quality; default 85; ignored for PNG | | `f` | string (`webp`, `jpg`, `png`) | Output format; default `webp` | #### Scenario: Valid transform parameters accepted - **WHEN** the request includes valid `?w=200&h=200&q=80&f=jpg` - **THEN** the system SHALL parse and apply all four parameters #### Scenario: Unknown query parameters ignored - **WHEN** the request includes query parameters not in the supported set - **THEN** the system SHALL ignore them without error #### Scenario: Invalid parameter value - **WHEN** `?w` or `?h` is not a positive integer, or `?q` is outside 1–100, or `?f` is not one of `webp`, `jpg`, `png` - **THEN** the system SHALL return a 400 Bad Request with a plain-text error message --- ### Requirement: Return 302 redirect to S3 URL Upon successfully resolving and caching the avatar image, the system SHALL respond with `302 Found` and a `Location` header pointing to the public S3 URL of the cached object. The response SHALL NOT include a `Cache-Control` header, ensuring browsers do not cache the redirect itself. #### Scenario: Successful resolution returns redirect - **WHEN** the identifier is resolved and the image is available in S3 - **THEN** the system SHALL respond with `302 Found` and `Location: https://{bucket}.s3.{region}.amazonaws.com/avatars/{did}/{cid}/{key}` #### Scenario: Redirect is not cached by browser - **WHEN** the 302 response is received by a browser - **THEN** the browser SHALL re-request the service on the next page load due to the absence of `Cache-Control` --- ### Requirement: Return 404 when no avatar is found If resolution succeeds but the user has no avatar set on any resolver, the system SHALL respond with `404 Not Found`. #### Scenario: User has no avatar - **WHEN** the profile record exists but contains no avatar blob reference - **THEN** the system SHALL respond with `404 Not Found` and a plain-text message --- ### Requirement: Return 404 when identifier cannot be resolved If the identifier cannot be resolved to a DID, or the DID document cannot be fetched, or no profile record exists, the system SHALL respond with `404 Not Found`. #### Scenario: Handle does not resolve - **WHEN** both DNS TXT and HTTPS fallback fail for the given handle - **THEN** the system SHALL respond with `404 Not Found` #### Scenario: Profile record missing - **WHEN** the PDS returns 404 for the profile record - **THEN** the system SHALL respond with `404 Not Found` --- ### Requirement: Return 502 on upstream failure If a PDS, plc.directory, or S3 operation fails due to a server-side or network error (not a 404), the system SHALL respond with `502 Bad Gateway`. #### Scenario: PDS unreachable - **WHEN** the PDS is unreachable or returns a 5xx response - **THEN** the system SHALL respond with `502 Bad Gateway` #### Scenario: S3 upload fails - **WHEN** the S3 upload fails with a non-client error - **THEN** the system SHALL respond with `502 Bad Gateway`