1478514b13cdffbe9ed1f2e2ff2a02d2339b2b3d
Implements Issue #11: Silo origin adapter This commit creates the SiloOrigin class that implements the FileOrigin interface introduced in Issue #9, enabling Silo to be used as a document origin in the unified file origin system. ## SiloOrigin Class (silo_origin.py) New Python module providing the FileOrigin implementation for Silo PLM: ### Identity Methods - id(): Returns 'silo' as unique identifier - name(): Returns 'Kindred Silo' for UI display - nickname(): Returns 'Silo' for compact UI elements - icon(): Returns 'silo' icon name - type(): Returns OriginType.PLM (1) ### Workflow Characteristics - tracksExternally(): True - Silo tracks documents in database - requiresAuthentication(): True - Silo requires login ### Capabilities - supportsRevisions(): True - supportsBOM(): True - supportsPartNumbers(): True - supportsAssemblies(): True ### Connection State - connectionState(): Checks auth status and API connectivity - connect(): Triggers Silo_Auth dialog if needed - disconnect(): Calls _client.logout() ### Document Identity (UUID-based tracking) - documentIdentity(): Returns SiloItemId (UUID) as primary identity - documentDisplayId(): Returns SiloPartNumber for human display - ownsDocument(): True if document has SiloItemId or SiloPartNumber ### Core Operations (delegate to existing commands) - newDocument(): Delegates to Silo_New command - openDocument(): Uses find_file_by_part_number or _sync.open_item - saveDocument(): Saves locally + uploads via _client._upload_file - saveDocumentAs(): Triggers migration workflow for local docs ### Extended Operations - commitDocument(): Delegates to Silo_Commit - pullDocument(): Delegates to Silo_Pull - pushDocument(): Delegates to Silo_Push - showInfo(): Delegates to Silo_Info - showBOM(): Delegates to Silo_BOM ### Module Functions - get_silo_origin(): Returns singleton instance - register_silo_origin(): Registers with FreeCADGui.addOrigin() - unregister_silo_origin(): Cleanup function ## UUID Tracking (silo_commands.py) Added SiloItemId property to all locations where Silo properties are set: 1. create_document_for_item() - Assembly objects (line 1115) 2. create_document_for_item() - Fallback Part objects (line 1131) 3. create_document_for_item() - Part objects (line 1145) 4. Silo_New.Activated() - Tagged existing objects (line 1471) The SiloItemId stores the database UUID (Item.ID) which is immutable, while SiloPartNumber remains the human-readable identifier that could theoretically change. Property structure on tracked objects: - SiloItemId: UUID from database (primary tracking key) - SiloPartNumber: Human-readable part number - SiloRevision: Current revision number - SiloItemType: 'part' or 'assembly' ## Workbench Integration (InitGui.py) SiloOrigin is automatically registered when the Silo workbench initializes: def Initialize(self): import silo_commands try: import silo_origin silo_origin.register_silo_origin() except Exception as e: FreeCAD.Console.PrintWarning(...) This makes Silo available as a file origin via: - FreeCADGui.listOrigins() -> includes 'silo' - FreeCADGui.getOrigin('silo') -> returns origin info dict - FreeCADGui.setActiveOrigin('silo') -> sets Silo as active ## Design Decisions 1. **Delegation Pattern**: SiloOrigin delegates to existing Silo commands rather than reimplementing logic, ensuring consistency and easier maintenance. 2. **UUID as Primary Identity**: documentIdentity() returns UUID (SiloItemId) for immutable tracking, while documentDisplayId() returns part number for user display. 3. **Graceful Fallback**: If SiloItemId is not present (legacy docs), falls back to SiloPartNumber for identity/ownership checks. 4. **Exception Handling**: All operations wrapped in try/except to prevent origin system failures from breaking FreeCAD. Refs: #11
Kindred Silo
Item database and part management system for Kindred Create.
Overview
Kindred Silo is an R&D-oriented item database with:
- Configurable part number generation via YAML schemas
- FreeCAD integration with git-like commands (checkout, commit, status)
- Revision tracking with append-only history
- BOM management with reference designators and alternates
- Physical inventory tracking with hierarchical locations
Components
silo/
├── cmd/
│ ├── silo/ # CLI tool
│ └── silod/ # API server
├── internal/
│ ├── api/ # HTTP handlers, routes, and templates
│ ├── config/ # Configuration loading
│ ├── db/ # PostgreSQL access
│ ├── migration/ # Property migration utilities
│ ├── partnum/ # Part number generation
│ ├── schema/ # YAML schema parsing
│ └── storage/ # MinIO file storage
├── pkg/
│ └── freecad/ # FreeCAD workbench (Python)
├── migrations/ # Database migration SQL scripts
├── schemas/ # Part numbering schema definitions (YAML)
├── deployments/ # Docker Compose and systemd configs
├── scripts/ # Deployment and setup scripts
└── docs/ # Documentation
Quick Start
# Database setup
psql -h psql.kindred.internal -U silo -d silo -f migrations/001_initial.sql
# Configure
cp config.example.yaml config.yaml
# Edit config.yaml with your settings
# Run server
go run ./cmd/silod
# CLI usage
go run ./cmd/silo register --schema kindred-rd --category F01
Configuration
See config.example.yaml for all options.
Kindred Create Integration
Install the workbench:
ln -s $(pwd)/pkg/freecad ~/.local/share/FreeCAD/Mod/KindredSilo
Then in Kindred Create, use the Silo workbench toolbar commands:
- Pull - Download an item by part number
- Commit - Save current state as a new revision with comment
- Push - Batch upload modified files
- Info - View revision history
License
MIT License - Copyright (c) 2026 Kindred Systems LLC
See LICENSE for details.
Languages
Go
68.5%
TypeScript
25.5%
Shell
2.7%
PLpgSQL
2.4%
Makefile
0.5%
Other
0.3%