Add stock quantity, datasheet URL, and HTTP caching to KiCad API

- Add Stock field showing total available quantity across all part lots
- Add Storage Location field when parts have stored locations
- Resolve actual datasheet PDF from attachments (by type name, attachment
  name, or first PDF) instead of always linking to Part-DB page
- Keep Part-DB page URL as separate "Part-DB URL" field
- Add ETag and Cache-Control headers to all KiCad API endpoints
- Support conditional requests (If-None-Match) returning 304
- Categories/part lists cached 5 min, part details cached 1 min
This commit is contained in:
Sebastian Almberg 2026-02-08 09:57:10 +01:00
parent c2a51e57b7
commit a40ffea95e
3 changed files with 157 additions and 12 deletions

View file

@ -148,6 +148,11 @@ class KiCadApiControllerTest extends WebTestCase
'value' => 'http://localhost/en/part/1/info',
'visible' => 'False',
),
'Part-DB URL' =>
array(
'value' => 'http://localhost/en/part/1/info',
'visible' => 'False',
),
'description' =>
array(
'value' => '',
@ -168,6 +173,11 @@ class KiCadApiControllerTest extends WebTestCase
'value' => '1',
'visible' => 'False',
),
'Stock' =>
array(
'value' => '0',
'visible' => 'False',
),
),
);
@ -221,6 +231,11 @@ class KiCadApiControllerTest extends WebTestCase
'value' => 'http://localhost/en/part/1/info',
'visible' => 'False',
),
'Part-DB URL' =>
array (
'value' => 'http://localhost/en/part/1/info',
'visible' => 'False',
),
'description' =>
array (
'value' => '',
@ -241,10 +256,42 @@ class KiCadApiControllerTest extends WebTestCase
'value' => '1',
'visible' => 'False',
),
'Stock' =>
array (
'value' => '0',
'visible' => 'False',
),
),
);
self::assertEquals($expected, $data);
}
public function testCategoriesHasCacheHeaders(): void
{
$client = $this->createClientWithCredentials();
$client->request('GET', self::BASE_URL.'/categories.json');
self::assertResponseIsSuccessful();
$response = $client->getResponse();
self::assertNotNull($response->headers->get('ETag'));
self::assertStringContainsString('max-age=', $response->headers->get('Cache-Control'));
}
public function testConditionalRequestReturns304(): void
{
$client = $this->createClientWithCredentials();
$client->request('GET', self::BASE_URL.'/categories.json');
$etag = $client->getResponse()->headers->get('ETag');
self::assertNotNull($etag);
//Make a conditional request with the ETag
$client->request('GET', self::BASE_URL.'/categories.json', [], [], [
'HTTP_IF_NONE_MATCH' => $etag,
]);
self::assertResponseStatusCodeSame(304);
}
}