Skip to content

Enhance KiCad integration: API v2, batch EDA editing, field export control#1241

Open
Sebbeben wants to merge 23 commits intoPart-DB:masterfrom
Sebbeben:feature/kicad-enhancements
Open

Enhance KiCad integration: API v2, batch EDA editing, field export control#1241
Sebbeben wants to merge 23 commits intoPart-DB:masterfrom
Sebbeben:feature/kicad-enhancements

Conversation

@Sebbeben
Copy link
Contributor

Summary

Comprehensive improvements to the KiCad HTTP Library API and EDA workflow, addressing several open issues.

KiCad API Enhancements

  • Stock quantity & storage location fields in API response
  • Datasheet PDF URL: Resolves actual PDF attachments instead of linking to Part-DB page (Part-DB inventory as KiCAD library? #395)
  • HTTP cache headers: ETag + Cache-Control for conditional requests
  • ?minimal=true query param: Faster category part loading for large categories
  • Category descriptions: Uses category comment when available
  • KiCad API v2 (/kicad-api/v2/): Adds volatile field support — Stock and Storage Location are shown in KiCad but NOT saved to schematic files

Configurable Field Export (#536)

  • Parameter kicad_export flag: Per-parameter checkbox to control which specifications are exposed to KiCad (e.g., tolerance, voltage rating)
  • Orderdetail kicad_export flag: Per-supplier control of which SPNs get exported. Backward compatible — if no checkbox is checked, all SPNs export as before.

CSV Import of EDA Fields (#614)

  • Support for kicad_symbol, kicad_footprint, kicad_reference, kicad_value, eda_visibility, eda_exclude_bom, eda_exclude_board, eda_exclude_sim columns in CSV part import
  • Enables bulk migration from existing KiCad database libraries

Batch EDA Editing (#554)

  • New batch action in parts table to edit EDA/KiCad fields for multiple selected parts
  • Supports: reference prefix, value, symbol, footprint, visibility, and exclude flags
  • Pre-populates shared values when all selected parts have the same value

BOM Import: Multi-Footprint Merging (#778)

  • When a BOM entry links to a Part-DB part (via ID or SPN), entries are merged by part ID regardless of footprint variant
  • Example: Same capacitor with standard and hand-solder pads merges into one BOM entry

EDA Status Indicator

  • New "EDA" column in parts datatable showing completeness at a glance
  • Green bolt = symbol + footprint + reference all set; Yellow bolt = partial
  • Clickable — opens directly to the part's EDA settings tab

Console Command: partdb:kicad:populate

  • Bulk-assigns KiCad symbol/footprint paths based on category/footprint mappings
  • Supports CSV mapping files, dry-run mode, and regex patterns
  • Useful for initial KiCad integration setup on large databases

Code Quality

  • Deduplicated KiCost supplier field generation (single loop instead of two)
  • Fixed redundant getEdaInfo() call in visibility check
  • Moved manf/manf# fields outside orderdetails conditional (always present)
  • Full PHPStan compliance, 1216 PHPUnit tests passing

Related Issues

Database Migrations

  • Version20260208190000: Adds kicad_export column to parameters table
  • Version20260210120000: Adds kicad_export column to orderdetails table

Test Plan

  • PHPStan: 0 errors (685 files)
  • PHPUnit: 1216 tests, 3080 assertions — all pass
  • New tests: KiCadHelperTest (unit), KiCadApiControllerTest (functional), PopulateKicadCommandTest, PartNormalizerTest
  • Manual UI testing: EDA status column, batch editing, orderdetail checkbox, BOM import with multi-footprint CSV
  • API testing: v1 and v2 endpoints verified with Bearer token auth

@codecov
Copy link

codecov bot commented Feb 11, 2026

Codecov Report

❌ Patch coverage is 88.61454% with 83 lines in your changes missing coverage. Please review.
✅ Project coverage is 55.82%. Comparing base (70cde4c) to head (5d9d24d).

Files with missing lines Patch % Lines
src/Command/PopulateKicadCommand.php 90.63% 34 Missing ⚠️
src/Controller/BatchEdaController.php 62.71% 22 Missing ⚠️
src/Services/EDA/KiCadHelper.php 87.64% 11 Missing ⚠️
src/Services/Parts/PartsTableActionHandler.php 0.00% 7 Missing ⚠️
src/Entity/PriceInformations/Orderdetail.php 40.00% 3 Missing ⚠️
src/Serializer/PartNormalizer.php 89.47% 2 Missing ⚠️
src/Services/ImportExportSystem/BOMImporter.php 77.77% 2 Missing ⚠️
src/Controller/KiCadApiV2Controller.php 96.55% 1 Missing ⚠️
src/DataTables/Helpers/PartDataTableHelper.php 96.55% 1 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##             master    #1241      +/-   ##
============================================
+ Coverage     54.77%   55.82%   +1.04%     
- Complexity     8012     8175     +163     
============================================
  Files           601      605       +4     
  Lines         25690    26388     +698     
============================================
+ Hits          14072    14731     +659     
- Misses        11618    11657      +39     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

- 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
- Add comprehensive KiCadHelperTest with 14 test cases covering:
  - Stock quantity calculation (zero, single lot, multiple lots)
  - Stock exclusion of expired and unknown-quantity lots
  - Storage location display (present, absent, multiple)
  - Datasheet URL resolution by type name, attachment name, PDF extension
  - Datasheet fallback to Part-DB URL when no match
  - "Data sheet" (with space) name variant matching
- Fix PDF extension detection for external attachments (getExtension()
  returns null for external-only attachments, now also parses URL path)
- Use empty Response instead of JsonResponse(null) for 304 Not Modified
  to avoid sending "null" as response body
- Guard parse_url() result with is_string() since it can return false
  for malformed URLs
- Move storage location tracking inside the availability check so
  expired and unknown-quantity lots don't contribute locations
The test was requesting /parts/1.json instead of /parts/2.json and had
Part 1's expected data. Now tests Part 2 which inherits EDA info from
its category and footprint, verifying the inheritance behavior.
Replace manual If-None-Match comparison with Response::setEtag() and
Response::isNotModified(), which properly handles ETag quoting, weak
vs strong comparison, and 304 response cleanup. Fixes PHPStan return
type error and CI test failures.
Add a kicad_export checkbox to parameters, allowing users to control
which specifications appear as fields in the KiCad HTTP library API.
Parameters with kicad_export enabled are included using their formatted
value, without overwriting hardcoded fields like description or Stock.
Console command that populates KiCad footprint/symbol paths on Footprint
and Category entities based on name-to-library mappings. Supports dry-run,
force overwrite, and list modes. Includes 130+ footprint mappings and 30+
category symbol mappings for KiCad 9.x standard libraries.
Add user-friendly column aliases (kicad_symbol, kicad_footprint,
kicad_reference, kicad_value, eda_exclude_bom, etc.) to the CSV import
system. Users can now bulk-set KiCad symbols, footprints, and other EDA
metadata via CSV/Excel import without knowing the internal dot notation.
Users can now select multiple parts in any parts table and batch-edit
their EDA/KiCad fields (symbol, footprint, reference prefix, value,
visibility, exclude from BOM/board/sim). Each field has an "Apply"
checkbox so users control exactly which fields are changed.
Add @var type annotations for Doctrine repository findAll() calls so
PHPStan can resolve getEdaInfo() on Footprint/Category entities. Fix
array return type for numeric-string keys and add explicit callback to
array_filter to satisfy strict rules.
- Add required=false to TriStateCheckboxType fields so HTML5 validation
  doesn't force users to check visibility/BOM/board checkboxes
- Pre-populate form fields when all selected parts share the same EDA
  value, so users can see current state before editing
…OM improvements

- Add KiCad API v2 endpoints (/kicad-api/v2) with volatile field support
  for stock and storage location (shown but not saved to schematic)
- Add kicad_export flag to Orderdetail entity for per-supplier SPN control
  (backward compatible: if no flag set, all SPNs exported as before)
- Add EDA completeness indicator column in parts datatable (bolt icon)
- Add ?minimal=true query param for faster category parts loading
- Improve category descriptions (use comment instead of URL when available)
- Improve BOM importer multi-footprint support: merge entries by Part-DB
  part ID when linked, tracking footprint variants in comments
- Fix KiCost manf/manf# fields always present (not conditional on orderdetails)
- Fix duplicate getEdaInfo() call in shouldPartBeVisible
- Consolidate supplier SPN and KiCost field generation into single loop
Add options default to ORM column definition so schema:update
works correctly on SQLite test databases.
New setting "Datasheet field links to PDF" in KiCad EDA settings.
When enabled (default), the datasheet field resolves to the actual
PDF attachment URL. When disabled, it links to the Part-DB page
(old behavior). Configurable via settings UI or EDA_KICAD_DATASHEET_AS_PDF env var.
The settings bundle stores values in the database. When upgrading from
a version without datasheetAsPdf, the stored JSON lacks this key,
causing a TypeError when assigning null to a non-nullable bool.
Making it nullable with a fallback in KiCadHelper fixes the upgrade path.
- KiCadApiV2ControllerTest: root, categories, parts, volatile fields,
  v1 vs v2 comparison, cache headers, 304 conditional request, auth
- BatchEdaControllerTest: page load, empty redirect, form submission
@Sebbeben Sebbeben force-pushed the feature/kicad-enhancements branch from b0caaff to 7e3aa7f Compare February 16, 2026 20:14
Add tests for: applying all EDA fields at once, custom redirect URL,
and verifying unchecked fields are skipped.
@Sebbeben Sebbeben force-pushed the feature/kicad-enhancements branch from bf677c2 to 06c6542 Compare February 16, 2026 20:37
@jbtronics
Copy link
Member

jbtronics commented Feb 17, 2026

Looks interesting thanks.

Some remarks:

  • The database migrationss should be merged

Kicad populate:

  • The populate kicad command, should be documented. List them at the console commands list docs and explain its use in the kicad docs page.
  • It is probably useful to check for the alternative names of categories and footprints too, if there are matches with the known list
  • I not sure if the current model with the mapping list hardcoded in the command is flexible enough for reality. Maybe it would make sense, to allow loading CSV or JSON file with the mapping, so that can be overwritten/extended by users. And supplying a default mapping list with Part-DB that is used, if there is no user supplied one. But this is probably not that important for start

Kicad API Controller

  • createCacheableJsonResponse is maybe a better fitting name for the function instead of createCachedJsonResponse
  • Have you tried if these caching tags makes a big difference in actual performance? I would have expected the limiting factor is the response time of symfony, not the data transfer.

KiCad v2 api

  • Do you have a link to the KiCAD v2 API documentation?

Abstract parameter & orderdetail

  • Maybe eda_visibility is a better name than kicad_export.
  • It might make sense to have an system option to set the default value for these. Either for newly created elements, or for all elements, where the value is not explictly set

Parameter type

  • The EDA export field should only be visible for parameters on parts, for other entities it has no function I think.

KiCAD Helper

  • For future proofing it is probably useful to not use a bool for switching between the different API version, but an integer number (with a check for our supported versions). Or use separate methods like getPartsV1() and getPartsV2()
  • It seems the manf field for KiCost was removed from the API response.

@Sebbeben
Copy link
Contributor Author

Thanks a lot for the thorough review and the great suggestions! Really appreciate you taking the time — several of these ideas (especially eda_visibility naming and the system-wide default) are much better than what I had.

Here's my plan for addressing everything:

Will implement:

  • Merge the two database migrations into one
  • Rename kicad_exporteda_visibility everywhere (entities, forms, templates, translations, tests, migration column name)
  • Rename createCachedJsonResponsecreateCacheableJsonResponse
  • Change bool $apiV2 to int $apiVersion with supported version validation
  • Make the EDA export field only visible for parameters on parts (not other entity types)
  • PopulateKicadCommand: also check alternative names of categories/footprints for matches against the mapping list
  • PopulateKicadCommand: support loading an external JSON mapping file (ship a default one with Part-DB)
  • Add system-wide default setting for eda_visibility (make the field nullable, null = use system default)
  • Document the populate command in the console commands list and KiCad docs page

Regarding the manf field: I believe it's still there — I moved it earlier in the method (before the orderdetails loop, under "always present, independent of orderdetails") so it's no longer tied to the supplier filtering logic. But the diff might make it look like a removal if you only see the old location. Please let me know if I'm missing something!

Regarding KiCad v2 API documentation:
The v2 spec with volatile fields is documented here, though it's still in a development branch and not yet part of the official KiCad docs:

The official v1 docs are at:

Question about v2: Since the KiCad HTTP Library v2 spec is still in a development branch and not finalized yet, do you think we should hold off on the v2 API controller until the spec is stable? Or is it fine to ship as-is? Happy to defer the v2 parts to a follow-up PR if you prefer — just let me know.

…rsioning

Changes based on jbtronics' review of PR Part-DB#1241:

- Rename kicad_export -> eda_visibility (entities, forms, templates,
  translations, tests) with nullable bool for system default support
- Merge two database migrations into one (Version20260211000000)
- Rename createCachedJsonResponse -> createCacheableJsonResponse
- Change bool $apiV2 -> int $apiVersion with version validation
- EDA visibility field only shown for part parameters, not other entities
- PopulateKicadCommand: check alternative names of footprints/categories
- PopulateKicadCommand: support external JSON mapping file (--mapping-file)
- Ship default mappings JSON at contrib/kicad-populate/default_mappings.json
- Add system-wide defaultEdaVisibility setting in KiCadEDASettings
- Add KiCad HTTP Library v2 spec link in controller docs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants