update documentation and specs
This commit is contained in:
21
LICENSE
Normal file
21
LICENSE
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2026 Kindred Systems LLC
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
42
README.md
42
README.md
@@ -1,10 +1,10 @@
|
|||||||
# Silo
|
# Kindred Silo
|
||||||
|
|
||||||
Item database and part management system for FreeCAD.
|
Item database and part management system for Kindred Create.
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
Silo is an R&D-oriented item database with:
|
Kindred Silo is an R&D-oriented item database with:
|
||||||
|
|
||||||
- **Configurable part number generation** via YAML schemas
|
- **Configurable part number generation** via YAML schemas
|
||||||
- **FreeCAD integration** with git-like commands (checkout, commit, status)
|
- **FreeCAD integration** with git-like commands (checkout, commit, status)
|
||||||
@@ -20,20 +20,19 @@ silo/
|
|||||||
│ ├── silo/ # CLI tool
|
│ ├── silo/ # CLI tool
|
||||||
│ └── silod/ # API server
|
│ └── silod/ # API server
|
||||||
├── internal/
|
├── internal/
|
||||||
|
│ ├── api/ # HTTP handlers, routes, and templates
|
||||||
│ ├── config/ # Configuration loading
|
│ ├── config/ # Configuration loading
|
||||||
│ ├── db/ # PostgreSQL access
|
│ ├── db/ # PostgreSQL access
|
||||||
│ ├── schema/ # YAML schema parsing
|
│ ├── migration/ # Property migration utilities
|
||||||
│ ├── storage/ # MinIO file storage
|
|
||||||
│ ├── partnum/ # Part number generation
|
│ ├── partnum/ # Part number generation
|
||||||
│ ├── inventory/ # Location and stock management
|
│ ├── schema/ # YAML schema parsing
|
||||||
│ └── api/ # HTTP handlers
|
│ └── storage/ # MinIO file storage
|
||||||
├── pkg/
|
├── pkg/
|
||||||
│ └── freecad/ # FreeCAD workbench (Python)
|
│ └── freecad/ # FreeCAD workbench (Python)
|
||||||
├── web/
|
├── migrations/ # Database migration SQL scripts
|
||||||
│ ├── templates/ # HTML templates
|
├── schemas/ # Part numbering schema definitions (YAML)
|
||||||
│ └── static/ # CSS, JS assets
|
├── deployments/ # Docker Compose and systemd configs
|
||||||
├── migrations/ # Database migrations
|
├── scripts/ # Deployment and setup scripts
|
||||||
├── schemas/ # Example YAML schemas
|
|
||||||
└── docs/ # Documentation
|
└── docs/ # Documentation
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -51,26 +50,29 @@ cp config.example.yaml config.yaml
|
|||||||
go run ./cmd/silod
|
go run ./cmd/silod
|
||||||
|
|
||||||
# CLI usage
|
# CLI usage
|
||||||
go run ./cmd/silo register --schema kindred-rd --project PROTO --type AS
|
go run ./cmd/silo register --schema kindred-rd --category F01
|
||||||
```
|
```
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
See `config.example.yaml` for all options.
|
See `config.example.yaml` for all options.
|
||||||
|
|
||||||
## FreeCAD Integration
|
## Kindred Create Integration
|
||||||
|
|
||||||
Install the workbench:
|
Install the workbench:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
ln -s $(pwd)/pkg/freecad ~/.local/share/FreeCAD/Mod/Silo
|
ln -s $(pwd)/pkg/freecad ~/.local/share/FreeCAD/Mod/KindredSilo
|
||||||
```
|
```
|
||||||
|
|
||||||
Then in FreeCAD:
|
Then in Kindred Create, use the Silo workbench toolbar commands:
|
||||||
- `silo checkout PROTO-AS-0001`
|
- **Pull** - Download an item by part number
|
||||||
- `silo commit -m "Updated dimensions"`
|
- **Commit** - Save current state as a new revision with comment
|
||||||
- `silo status`
|
- **Push** - Batch upload modified files
|
||||||
|
- **Info** - View revision history
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
Proprietary - Kindred Systems LLC
|
MIT License - Copyright (c) 2026 Kindred Systems LLC
|
||||||
|
|
||||||
|
See [LICENSE](LICENSE) for details.
|
||||||
|
|||||||
53
ROADMAP.md
53
ROADMAP.md
@@ -102,7 +102,7 @@ This document compares Silo's current capabilities against SOLIDWORKS PDM—the
|
|||||||
|
|
||||||
| Feature | Status | Notes |
|
| Feature | Status | Notes |
|
||||||
|---------|--------|-------|
|
|---------|--------|-------|
|
||||||
| FreeCAD Workbench | ~60% | Commands defined, upload/commit working, needs testing |
|
| FreeCAD Workbench | ~80% | 8 commands implemented (save, commit, pull, push, info, register, open, browse), needs end-to-end testing |
|
||||||
| Date segment type | Not started | Schema parser placeholder exists |
|
| Date segment type | Not started | Schema parser placeholder exists |
|
||||||
| Part number validation | Not started | API accepts but doesn't validate format |
|
| Part number validation | Not started | API accepts but doesn't validate format |
|
||||||
| Location hierarchy CRUD | Schema only | Tables exist, no API endpoints |
|
| Location hierarchy CRUD | Schema only | Tables exist, no API endpoints |
|
||||||
@@ -113,10 +113,12 @@ This document compares Silo's current capabilities against SOLIDWORKS PDM—the
|
|||||||
|
|
||||||
| Component | Status |
|
| Component | Status |
|
||||||
|-----------|--------|
|
|-----------|--------|
|
||||||
| PostgreSQL | Running |
|
| PostgreSQL | Running (psql.kindred.internal) |
|
||||||
| MinIO | Configured (CPU compatibility issue being resolved) |
|
| MinIO | Configured in Docker Compose |
|
||||||
| Silo API Server | Builds successfully |
|
| Silo API Server | Builds successfully |
|
||||||
| Docker Compose | Complete with all services |
|
| Docker Compose | Complete (dev and production) |
|
||||||
|
| systemd service | Unit file and env template ready |
|
||||||
|
| Deployment scripts | setup-host, deploy, init-db, setup-ipa-nginx |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -308,8 +310,11 @@ File storage works well. Thumbnail generation and file preview would significant
|
|||||||
|
|
||||||
| Feature | Description | Status |
|
| Feature | Description | Status |
|
||||||
|---------|-------------|--------|
|
|---------|-------------|--------|
|
||||||
| MinIO integration | Resolve CPU compatibility, test upload/download | In Progress |
|
| MinIO integration | File upload/download with versioning and checksums | Complete |
|
||||||
| FreeCAD workbench | Complete and test checkout/commit/status commands | In Progress |
|
| FreeCAD workbench | 8 toolbar commands implemented | Needs Testing |
|
||||||
|
| Revision control | Rollback, comparison, status/labels | Complete |
|
||||||
|
| CSV import/export | Dry-run validation, template generation | Complete |
|
||||||
|
| Project management | CRUD, many-to-many item tagging | Complete |
|
||||||
| Unit tests | Core API and database operations | Not Started |
|
| Unit tests | Core API and database operations | Not Started |
|
||||||
| Date segment type | Support date-based part number segments | Not Started |
|
| Date segment type | Support date-based part number segments | Not Started |
|
||||||
| Part number validation | Validate format on creation | Not Started |
|
| Part number validation | Validate format on creation | Not Started |
|
||||||
@@ -384,19 +389,16 @@ File storage works well. Thumbnail generation and file preview would significant
|
|||||||
|
|
||||||
### Phase 1 Detailed Tasks
|
### Phase 1 Detailed Tasks
|
||||||
|
|
||||||
#### 1.1 MinIO Integration Completion
|
#### 1.1 MinIO Integration -- COMPLETE
|
||||||
- [ ] Verify MinIO container runs on target VM
|
- [x] MinIO service configured in Docker Compose
|
||||||
- [ ] Test file upload via REST API
|
- [x] File upload via REST API
|
||||||
- [ ] Test file download via REST API
|
- [x] File download via REST API (latest and by revision)
|
||||||
- [ ] Test FreeCAD workbench upload
|
- [x] SHA256 checksums on upload
|
||||||
- [ ] Verify version history in MinIO console
|
|
||||||
|
|
||||||
#### 1.2 FreeCAD Workbench Completion
|
#### 1.2 FreeCAD Workbench -- Needs End-to-End Testing
|
||||||
- [ ] Test `silo checkout` command
|
- [x] Silo_Save, Silo_Commit, Silo_Pull, Silo_Push implemented
|
||||||
- [ ] Test `silo commit` with file upload
|
- [x] Silo_Info, Silo_Register, Silo_Open, Silo_Browse implemented
|
||||||
- [ ] Test `silo status` for modification detection
|
- [ ] End-to-end testing with running Silo instance
|
||||||
- [ ] Test `silo log` for revision history
|
|
||||||
- [ ] Test `silo register` for new part creation
|
|
||||||
- [ ] Document workbench installation
|
- [ ] Document workbench installation
|
||||||
|
|
||||||
#### 1.3 Unit Test Suite
|
#### 1.3 Unit Test Suite
|
||||||
@@ -411,7 +413,6 @@ File storage works well. Thumbnail generation and file preview would significant
|
|||||||
#### 1.4 Missing Segment Types
|
#### 1.4 Missing Segment Types
|
||||||
- [ ] Implement date segment type
|
- [ ] Implement date segment type
|
||||||
- [ ] Add strftime-style format support
|
- [ ] Add strftime-style format support
|
||||||
- [ ] Update schema documentation
|
|
||||||
|
|
||||||
#### 1.5 Location & Inventory APIs
|
#### 1.5 Location & Inventory APIs
|
||||||
- [ ] `GET /api/locations` - List locations
|
- [ ] `GET /api/locations` - List locations
|
||||||
@@ -460,8 +461,10 @@ File storage works well. Thumbnail generation and file preview would significant
|
|||||||
- [SOLIDWORKS PDM API Getting Started](https://3dswym.3dexperience.3ds.com/wiki/solidworks-news-info/getting-started-with-the-solidworks-pdm-api-solidpractices_gBCYaM75RgORBcpSO1m_Mw)
|
- [SOLIDWORKS PDM API Getting Started](https://3dswym.3dexperience.3ds.com/wiki/solidworks-news-info/getting-started-with-the-solidworks-pdm-api-solidpractices_gBCYaM75RgORBcpSO1m_Mw)
|
||||||
|
|
||||||
### Silo Documentation
|
### Silo Documentation
|
||||||
- [Silo Specification](docs/SPECIFICATION.md)
|
- [Specification](docs/SPECIFICATION.md)
|
||||||
- [Development Status](docs/STATUS.md)
|
- [Development Status](docs/STATUS.md)
|
||||||
|
- [Deployment Guide](docs/DEPLOYMENT.md)
|
||||||
|
- [Gap Analysis](docs/GAP_ANALYSIS.md)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -472,21 +475,25 @@ File storage works well. Thumbnail generation and file preview would significant
|
|||||||
| **Version Control** | Check-in/out | Yes | Yes | No | Phase 2 |
|
| **Version Control** | Check-in/out | Yes | Yes | No | Phase 2 |
|
||||||
| | Version history | Yes | Yes | Yes | - |
|
| | Version history | Yes | Yes | Yes | - |
|
||||||
| | Rollback | Yes | Yes | Yes | - |
|
| | Rollback | Yes | Yes | Yes | - |
|
||||||
|
| | Revision labels/status | Yes | Yes | Yes | - |
|
||||||
|
| | Revision comparison | Yes | Yes | Yes (metadata) | - |
|
||||||
| **Workflow** | Custom workflows | Limited | Yes | No | Phase 3 |
|
| **Workflow** | Custom workflows | Limited | Yes | No | Phase 3 |
|
||||||
| | Parallel approval | No | Yes | No | Phase 3 |
|
| | Parallel approval | No | Yes | No | Phase 3 |
|
||||||
| | Notifications | No | Yes | No | Phase 3 |
|
| | Notifications | No | Yes | No | Phase 3 |
|
||||||
| **Security** | User auth | Windows | Windows/LDAP | No | Phase 2 |
|
| **Security** | User auth | Windows | Windows/LDAP | No | Phase 2 |
|
||||||
| | Permissions | Basic | Granular | No | Phase 2 |
|
| | Permissions | Basic | Granular | No | Phase 2 |
|
||||||
| | Audit trail | Basic | Full | No | Phase 2 |
|
| | Audit trail | Basic | Full | No | Phase 2 |
|
||||||
| **Search** | Metadata search | Yes | Yes | Partial | Phase 4 |
|
| **Search** | Metadata search | Yes | Yes | Partial (API) | Phase 4 |
|
||||||
| | Content search | No | Yes | No | Phase 4 |
|
| | Content search | No | Yes | No | Phase 4 |
|
||||||
| | Where-used | Yes | Yes | No | Phase 4 |
|
| | Where-used | Yes | Yes | No | Phase 4 |
|
||||||
| **BOM** | Single-level | Yes | Yes | Yes | - |
|
| **BOM** | Single-level | Yes | Yes | Yes | - |
|
||||||
| | Multi-level | Yes | Yes | Schema only | Phase 5 |
|
| | Multi-level | Yes | Yes | Schema only | Phase 5 |
|
||||||
| | BOM export | Yes | Yes | No | Phase 5 |
|
| | BOM export | Yes | Yes | No | Phase 5 |
|
||||||
| **Integration** | API | Limited | Full | Full REST | - |
|
| **Data** | CSV import/export | Yes | Yes | Yes | - |
|
||||||
|
| | Project management | Yes | Yes | Yes | - |
|
||||||
|
| **Integration** | API | Limited | Full | Full REST (35+) | - |
|
||||||
| | ERP connectors | No | Yes | No | Phase 6 |
|
| | ERP connectors | No | Yes | No | Phase 6 |
|
||||||
| | Web access | No | Yes | Partial | Phase 4 |
|
| | Web access | No | Yes | Yes (htmx) | Phase 4 |
|
||||||
| **Files** | Versioning | Yes | Yes | Yes | - |
|
| **Files** | Versioning | Yes | Yes | Yes | - |
|
||||||
| | Preview | Yes | Yes | No | Phase 6 |
|
| | Preview | Yes | Yes | No | Phase 6 |
|
||||||
| | Multi-site | No | Yes | No | Not Planned |
|
| | Multi-site | No | Yes | No | Not Planned |
|
||||||
|
|||||||
@@ -17,21 +17,24 @@ This document analyzes the current state of the Silo project against its specifi
|
|||||||
|
|
||||||
| Document | Coverage | Status |
|
| Document | Coverage | Status |
|
||||||
|----------|----------|--------|
|
|----------|----------|--------|
|
||||||
| `README.md` | Quick start, overview | Partial (50%) |
|
| `README.md` | Quick start, overview, component map | Current |
|
||||||
| `docs/SPECIFICATION.md` | Design specification | Comprehensive (90%) |
|
| `docs/SPECIFICATION.md` | Design specification, API reference | Current |
|
||||||
| `docs/STATUS.md` | Development progress | Current but incomplete |
|
| `docs/STATUS.md` | Implementation status summary | Current |
|
||||||
| `silo-spec.md` | Duplicate of SPECIFICATION.md | Redundant |
|
| `docs/DEPLOYMENT.md` | Production deployment guide | Current |
|
||||||
|
| `docs/GAP_ANALYSIS.md` | SOLIDWORKS PDM comparison, roadmap | Current |
|
||||||
|
| `ROADMAP.md` | Feature roadmap and phases | Current |
|
||||||
|
| `silo-spec.md` | Redirect to `docs/SPECIFICATION.md` | Consolidated |
|
||||||
|
|
||||||
### 1.2 Documentation Gaps (Priority Order)
|
### 1.2 Documentation Gaps (Priority Order)
|
||||||
|
|
||||||
#### High Priority
|
#### High Priority
|
||||||
|
|
||||||
| Gap | Impact | Effort |
|
| Gap | Impact | Effort | Status |
|
||||||
|-----|--------|--------|
|
|-----|--------|--------|--------|
|
||||||
| **API Reference** | Users cannot integrate programmatically | Medium |
|
| **API Reference** | Users cannot integrate programmatically | Medium | Addressed in SPECIFICATION.md Section 11 |
|
||||||
| **Deployment Guide** | Cannot deploy to production | Medium |
|
| **Deployment Guide** | Cannot deploy to production | Medium | Complete (`docs/DEPLOYMENT.md`) |
|
||||||
| **Database Schema Guide** | Migration troubleshooting difficult | Low |
|
| **Database Schema Guide** | Migration troubleshooting difficult | Low | Open |
|
||||||
| **Configuration Reference** | config.yaml options undocumented | Low |
|
| **Configuration Reference** | config.yaml options undocumented | Low | Open |
|
||||||
|
|
||||||
#### Medium Priority
|
#### Medium Priority
|
||||||
|
|
||||||
@@ -52,10 +55,11 @@ This document analyzes the current state of the Silo project against its specifi
|
|||||||
|
|
||||||
### 1.3 Recommended Actions
|
### 1.3 Recommended Actions
|
||||||
|
|
||||||
1. **Consolidate specs**: Remove `silo-spec.md` duplicate
|
1. ~~**Consolidate specs**: Remove `silo-spec.md` duplicate~~ Done
|
||||||
2. **Create `docs/API.md`**: Full REST endpoint documentation with examples
|
2. ~~**Create API reference**: Full REST endpoint documentation~~ Addressed in SPECIFICATION.md
|
||||||
3. **Create `docs/DEPLOYMENT.md`**: Production deployment guide
|
3. ~~**Create `docs/DEPLOYMENT.md`**: Production deployment guide~~ Done
|
||||||
4. **Expand README.md**: Add configuration reference section
|
4. **Create configuration reference**: Document all `config.yaml` options
|
||||||
|
5. **Create database schema guide**: Document migrations and troubleshooting
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -124,21 +128,21 @@ CREATE TABLE revisions (
|
|||||||
|
|
||||||
### 3.1 Critical Gaps
|
### 3.1 Critical Gaps
|
||||||
|
|
||||||
| Gap | Description | Impact |
|
| Gap | Description | Impact | Status |
|
||||||
|-----|-------------|--------|
|
|-----|-------------|--------|--------|
|
||||||
| **No rollback** | Cannot revert to previous revision | Data recovery difficult |
|
| ~~**No rollback**~~ | ~~Cannot revert to previous revision~~ | ~~Data recovery difficult~~ | **Implemented** |
|
||||||
| **No comparison** | Cannot diff between revisions | Change tracking manual |
|
| ~~**No comparison**~~ | ~~Cannot diff between revisions~~ | ~~Change tracking manual~~ | **Implemented** |
|
||||||
| **No locking** | No concurrent edit protection | Multi-user unsafe |
|
| **No locking** | No concurrent edit protection | Multi-user unsafe | Open |
|
||||||
| **No approval workflow** | No release/sign-off process | Quality control gap |
|
| **No approval workflow** | No release/sign-off process | Quality control gap | Open |
|
||||||
|
|
||||||
### 3.2 Important Gaps
|
### 3.2 Important Gaps
|
||||||
|
|
||||||
| Gap | Description | Impact |
|
| Gap | Description | Impact | Status |
|
||||||
|-----|-------------|--------|
|
|-----|-------------|--------|--------|
|
||||||
| **No branching** | Linear history only | No experimental variants |
|
| **No branching** | Linear history only | No experimental variants | Open |
|
||||||
| **No tagging** | No named milestones | Release tracking manual |
|
| ~~**No tagging**~~ | ~~No named milestones~~ | ~~Release tracking manual~~ | **Implemented** (revision labels) |
|
||||||
| **No audit log** | Actions not logged separately | Compliance gap |
|
| **No audit log** | Actions not logged separately | Compliance gap | Open |
|
||||||
| **Thumbnail missing** | Schema exists, not populated | No visual preview |
|
| **Thumbnail missing** | Schema exists, not populated | No visual preview | Open |
|
||||||
|
|
||||||
### 3.3 Nice-to-Have Gaps
|
### 3.3 Nice-to-Have Gaps
|
||||||
|
|
||||||
@@ -153,66 +157,15 @@ CREATE TABLE revisions (
|
|||||||
|
|
||||||
## 4. Revision Control Roadmap
|
## 4. Revision Control Roadmap
|
||||||
|
|
||||||
### Phase 1: Foundation (Recommended First)
|
### Phase 1: Foundation -- COMPLETE
|
||||||
|
|
||||||
**Goal:** Enable safe single-user revision management
|
**Goal:** Enable safe single-user revision management
|
||||||
|
|
||||||
#### 1.1 Rollback Support
|
All Phase 1 items have been implemented:
|
||||||
```
|
|
||||||
Effort: Medium | Priority: High | Risk: Low
|
|
||||||
```
|
|
||||||
|
|
||||||
**Changes Required:**
|
- **Rollback**: `POST /api/items/{pn}/revisions/{rev}/rollback` - creates new revision from old
|
||||||
- Add `POST /api/items/{pn}/rollback/{rev}` endpoint
|
- **Revision Comparison**: `GET /api/items/{pn}/revisions/compare?from={rev1}&to={rev2}` - property and file diffs
|
||||||
- Create new revision copying properties/file from target revision
|
- **Revision Labels/Status**: `PATCH /api/items/{pn}/revisions/{rev}` - status (draft/review/released/obsolete) and arbitrary labels via migration 007
|
||||||
- FreeCAD: Add `Silo_Rollback` command
|
|
||||||
|
|
||||||
**Database:** No schema changes needed (creates new revision from old)
|
|
||||||
|
|
||||||
#### 1.2 Revision Comparison API
|
|
||||||
```
|
|
||||||
Effort: Medium | Priority: High | Risk: Low
|
|
||||||
```
|
|
||||||
|
|
||||||
**Changes Required:**
|
|
||||||
- Add `GET /api/items/{pn}/revisions/compare?from={rev1}&to={rev2}` endpoint
|
|
||||||
- Return property diff (added/removed/changed keys)
|
|
||||||
- Return file metadata diff (size, checksum changes)
|
|
||||||
|
|
||||||
**Implementation:**
|
|
||||||
```go
|
|
||||||
type RevisionDiff struct {
|
|
||||||
FromRevision int `json:"from_revision"`
|
|
||||||
ToRevision int `json:"to_revision"`
|
|
||||||
Properties PropertyDiff `json:"properties"`
|
|
||||||
FileChanged bool `json:"file_changed"`
|
|
||||||
FileSizeDiff int64 `json:"file_size_diff,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type PropertyDiff struct {
|
|
||||||
Added map[string]any `json:"added,omitempty"`
|
|
||||||
Removed map[string]any `json:"removed,omitempty"`
|
|
||||||
Changed map[string]PropertyChange `json:"changed,omitempty"`
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 1.3 Revision Labels/Status
|
|
||||||
```
|
|
||||||
Effort: Low | Priority: Medium | Risk: Low
|
|
||||||
```
|
|
||||||
|
|
||||||
**Database Migration:**
|
|
||||||
```sql
|
|
||||||
ALTER TABLE revisions ADD COLUMN status TEXT DEFAULT 'draft';
|
|
||||||
-- Values: 'draft', 'review', 'released', 'obsolete'
|
|
||||||
|
|
||||||
ALTER TABLE revisions ADD COLUMN labels TEXT[] DEFAULT '{}';
|
|
||||||
-- Arbitrary tags: ['prototype', 'v1.0', 'customer-approved']
|
|
||||||
```
|
|
||||||
|
|
||||||
**API Changes:**
|
|
||||||
- Add `PATCH /api/items/{pn}/revisions/{rev}` for status/label updates
|
|
||||||
- Add filtering by status in list endpoint
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -375,13 +328,13 @@ Effort: Medium | Priority: Low | Risk: Low
|
|||||||
|
|
||||||
## 5. Recommended Implementation Order
|
## 5. Recommended Implementation Order
|
||||||
|
|
||||||
### Immediate (Next Sprint)
|
### Completed
|
||||||
|
|
||||||
1. **Revision Comparison API** - High value, low risk
|
1. ~~**Revision Comparison API**~~ - Implemented
|
||||||
2. **Rollback Support** - Critical for data safety
|
2. ~~**Rollback Support**~~ - Implemented
|
||||||
3. **Revision Labels** - Quick win for workflow
|
3. ~~**Revision Labels/Status**~~ - Implemented (migration 007)
|
||||||
|
|
||||||
### Short-term (1-2 Months)
|
### Next (Short-term)
|
||||||
|
|
||||||
4. **Pessimistic Locking** - Required before multi-user
|
4. **Pessimistic Locking** - Required before multi-user
|
||||||
5. **Authentication** - Required before production deployment
|
5. **Authentication** - Required before production deployment
|
||||||
@@ -438,10 +391,11 @@ These design decisions remain unresolved:
|
|||||||
|
|
||||||
## Appendix A: File Structure for New Features
|
## Appendix A: File Structure for New Features
|
||||||
|
|
||||||
|
Revision endpoints, status, and labels are already implemented in the existing handler files. Future features would add:
|
||||||
|
|
||||||
```
|
```
|
||||||
internal/
|
internal/
|
||||||
api/
|
api/
|
||||||
handlers_revision.go # New revision endpoints
|
|
||||||
handlers_lock.go # Locking endpoints
|
handlers_lock.go # Locking endpoints
|
||||||
handlers_audit.go # Audit log endpoints
|
handlers_audit.go # Audit log endpoints
|
||||||
auth/
|
auth/
|
||||||
@@ -452,7 +406,6 @@ internal/
|
|||||||
audit.go # Audit repository
|
audit.go # Audit repository
|
||||||
releases.go # Release repository
|
releases.go # Release repository
|
||||||
migrations/
|
migrations/
|
||||||
007_revision_status.sql # Labels and status
|
|
||||||
008_item_locks.sql # Locking table
|
008_item_locks.sql # Locking table
|
||||||
009_audit_log.sql # Audit logging
|
009_audit_log.sql # Audit logging
|
||||||
010_releases.sql # Release management
|
010_releases.sql # Release management
|
||||||
@@ -462,10 +415,10 @@ migrations/
|
|||||||
|
|
||||||
## Appendix B: API Additions Summary
|
## Appendix B: API Additions Summary
|
||||||
|
|
||||||
### Phase 1 Endpoints
|
### Phase 1 Endpoints (Implemented)
|
||||||
```
|
```
|
||||||
GET /api/items/{pn}/revisions/compare # Diff two revisions
|
GET /api/items/{pn}/revisions/compare # Diff two revisions
|
||||||
POST /api/items/{pn}/rollback/{rev} # Create revision from old
|
POST /api/items/{pn}/revisions/{rev}/rollback # Create revision from old
|
||||||
PATCH /api/items/{pn}/revisions/{rev} # Update status/labels
|
PATCH /api/items/{pn}/revisions/{rev} # Update status/labels
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -75,8 +75,8 @@ Silo treats **part numbering schemas as configuration, not code**. Multiple numb
|
|||||||
| Database | PostgreSQL | Existing instance at psql.kindred.internal |
|
| Database | PostgreSQL | Existing instance at psql.kindred.internal |
|
||||||
| File Storage | MinIO | S3-compatible, versioning enabled |
|
| File Storage | MinIO | S3-compatible, versioning enabled |
|
||||||
| FreeCAD Integration | Python workbench | Macro-style commands |
|
| FreeCAD Integration | Python workbench | Macro-style commands |
|
||||||
| CLI | Go or Python | TBD based on complexity |
|
| CLI & API Server | Go (1.23) | chi/v5 router, pgx/v5 driver, zerolog |
|
||||||
| Web UI | Go + htmx | Lightweight, minimal JS |
|
| Web UI | Go html/template + htmx | Lightweight, minimal JS |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -186,7 +186,7 @@ Schemas define how part numbers are generated. Each schema consists of **segment
|
|||||||
# /etc/silo/schemas/kindred-rd.yaml
|
# /etc/silo/schemas/kindred-rd.yaml
|
||||||
schema:
|
schema:
|
||||||
name: kindred-rd
|
name: kindred-rd
|
||||||
version: 1
|
version: 3
|
||||||
description: "Kindred Systems R&D part numbering"
|
description: "Kindred Systems R&D part numbering"
|
||||||
|
|
||||||
# Separator between segments (default: "-")
|
# Separator between segments (default: "-")
|
||||||
@@ -194,45 +194,47 @@ schema:
|
|||||||
|
|
||||||
# Uniqueness enforcement
|
# Uniqueness enforcement
|
||||||
uniqueness:
|
uniqueness:
|
||||||
scope: global # or "per-project", "per-type", "per-schema"
|
scope: global
|
||||||
|
case_sensitive: false
|
||||||
|
|
||||||
segments:
|
segments:
|
||||||
- name: project
|
- name: category
|
||||||
type: string
|
|
||||||
length: 5
|
|
||||||
description: "Project identifier"
|
|
||||||
validation:
|
|
||||||
pattern: "^[A-Z0-9]{5}$"
|
|
||||||
required: true
|
|
||||||
|
|
||||||
- name: part_type
|
|
||||||
type: enum
|
type: enum
|
||||||
description: "Type of item"
|
description: "Category code (2-3 characters)"
|
||||||
values:
|
|
||||||
AS: "Assembly"
|
|
||||||
PT: "Part"
|
|
||||||
DW: "Drawing"
|
|
||||||
DC: "Document"
|
|
||||||
TB: "Tooling/Fixture"
|
|
||||||
PC: "Purchased Component"
|
|
||||||
required: true
|
required: true
|
||||||
|
values:
|
||||||
|
F01: "Hex Cap Screw"
|
||||||
|
F02: "Socket Head Cap Screw"
|
||||||
|
# ... 70+ categories across:
|
||||||
|
# F01-F18: Fasteners
|
||||||
|
# C01-C17: Fluid Fittings
|
||||||
|
# R01-R44: Motion Components
|
||||||
|
# S01-S17: Structural Materials
|
||||||
|
# E01-E27: Electrical Components
|
||||||
|
# M01-M18: Mechanical Components
|
||||||
|
# T01-T08: Tooling and Fixtures
|
||||||
|
# A01-A07: Assemblies
|
||||||
|
# P01-P05: Purchased/Off-the-Shelf
|
||||||
|
# X01-X08: Custom Fabricated Parts
|
||||||
|
|
||||||
- name: sequence
|
- name: sequence
|
||||||
type: serial
|
type: serial
|
||||||
length: 4
|
length: 4
|
||||||
padding: "0" # left-pad with zeros
|
padding: "0"
|
||||||
description: "Sequential number"
|
start: 1
|
||||||
scope: "{project}-{part_type}" # counter scope (template)
|
description: "Sequential number within category"
|
||||||
|
scope: "{category}"
|
||||||
|
|
||||||
# Format template (optional, defaults to joining segments with separator)
|
format: "{category}-{sequence}"
|
||||||
format: "{project}-{part_type}-{sequence}"
|
|
||||||
|
|
||||||
# Example outputs:
|
# Example outputs:
|
||||||
# PROTO-AS-0001 (first assembly in PROTO project)
|
# F01-0001 (first hex cap screw)
|
||||||
# PROTO-PT-0001 (first part in PROTO project)
|
# R27-0001 (first linear rail)
|
||||||
# ALPHA-AS-0001 (first assembly in ALPHA project)
|
# A01-0001 (first assembly)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> **Note:** The schema was migrated from a `{project}-{type}-{sequence}` format (v1) to `{category}-{sequence}` (v3). Projects are now managed as many-to-many tags on items rather than embedded in the part number. See `migrations/006_project_tags.sql`.
|
||||||
|
|
||||||
### 4.2 Segment Types
|
### 4.2 Segment Types
|
||||||
|
|
||||||
| Type | Description | Options |
|
| Type | Description | Options |
|
||||||
@@ -248,11 +250,8 @@ schema:
|
|||||||
The `scope` field in serial segments supports template variables referencing other segments:
|
The `scope` field in serial segments supports template variables referencing other segments:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
# Sequence per project
|
# Sequence per category (current kindred-rd schema)
|
||||||
scope: "{project}"
|
scope: "{category}"
|
||||||
|
|
||||||
# Sequence per project AND type (recommended for R&D)
|
|
||||||
scope: "{project}-{part_type}"
|
|
||||||
|
|
||||||
# Global sequence (no scope)
|
# Global sequence (no scope)
|
||||||
scope: null
|
scope: null
|
||||||
@@ -352,19 +351,18 @@ assembly_config:
|
|||||||
|
|
||||||
### 5.1 Workbench Commands
|
### 5.1 Workbench Commands
|
||||||
|
|
||||||
The Silo workbench provides git-like commands accessible via toolbar, menu, and Python console:
|
The Silo workbench provides toolbar commands in FreeCAD:
|
||||||
|
|
||||||
| Command | Description |
|
| Command | Description | Status |
|
||||||
|---------|-------------|
|
|---------|-------------|--------|
|
||||||
| `silo init` | Initialize Silo tracking for current document |
|
| `Silo_Save` | Auto-save document and upload to MinIO | Implemented |
|
||||||
| `silo status` | Show tracked/untracked objects, modifications |
|
| `Silo_Commit` | Save with revision comment | Implemented |
|
||||||
| `silo checkout <part_number>` | Load item from Silo into current document |
|
| `Silo_Pull` | Download item by part number / create new | Implemented |
|
||||||
| `silo commit` | Save current state as new revision |
|
| `Silo_Push` | Batch upload modified files | Implemented |
|
||||||
| `silo log` | Show revision history |
|
| `Silo_Info` | View revision history for current item | Implemented |
|
||||||
| `silo diff` | Compare current state to last committed revision |
|
| `Silo_Register` | Generate part number for current document | Implemented |
|
||||||
| `silo register` | Generate part number for selected object(s) |
|
| `Silo_Open` | Open item from Silo by part number | Implemented |
|
||||||
| `silo link` | Create relationship between objects |
|
| `Silo_Browse` | Browse items in a list dialog | Implemented |
|
||||||
| `silo bom` | Generate BOM from current assembly |
|
|
||||||
|
|
||||||
### 5.2 Property Synchronization
|
### 5.2 Property Synchronization
|
||||||
|
|
||||||
@@ -566,77 +564,118 @@ auth:
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 11. API Design (Sketch)
|
## 11. API Design
|
||||||
|
|
||||||
### 11.1 REST Endpoints
|
### 11.1 REST Endpoints (Implemented)
|
||||||
|
|
||||||
```
|
```
|
||||||
|
# Health
|
||||||
|
GET /health # Basic health check
|
||||||
|
GET /ready # Readiness (DB + MinIO)
|
||||||
|
|
||||||
|
# Web UI
|
||||||
|
GET / # Items page
|
||||||
|
GET /schemas # Schemas page
|
||||||
|
|
||||||
|
# Schemas
|
||||||
|
GET /api/schemas # List all schemas
|
||||||
|
GET /api/schemas/{name} # Get schema details
|
||||||
|
GET /api/schemas/{name}/properties # Get property schema for category
|
||||||
|
POST /api/schemas/{name}/segments/{segment}/values # Add enum value
|
||||||
|
PUT /api/schemas/{name}/segments/{segment}/values/{code} # Update enum value
|
||||||
|
DELETE /api/schemas/{name}/segments/{segment}/values/{code} # Delete enum value
|
||||||
|
|
||||||
|
# Projects
|
||||||
|
GET /api/projects # List projects
|
||||||
|
POST /api/projects # Create project
|
||||||
|
GET /api/projects/{code} # Get project
|
||||||
|
PUT /api/projects/{code} # Update project
|
||||||
|
DELETE /api/projects/{code} # Delete project
|
||||||
|
GET /api/projects/{code}/items # Get project items
|
||||||
|
|
||||||
# Items
|
# Items
|
||||||
GET /api/items # List/search items
|
GET /api/items # List/search items
|
||||||
POST /api/items # Create item
|
POST /api/items # Create item
|
||||||
GET /api/items/{part_number} # Get item details
|
GET /api/items/export.csv # Export items to CSV
|
||||||
PUT /api/items/{part_number} # Update item (creates revision)
|
POST /api/items/import # Import items from CSV
|
||||||
DELETE /api/items/{part_number} # Archive item
|
GET /api/items/template.csv # Get CSV import template
|
||||||
|
GET /api/items/{partNumber} # Get item details
|
||||||
|
PUT /api/items/{partNumber} # Update item
|
||||||
|
DELETE /api/items/{partNumber} # Archive item
|
||||||
|
|
||||||
|
# Item-Project Tags
|
||||||
|
GET /api/items/{partNumber}/projects # Get item's projects
|
||||||
|
POST /api/items/{partNumber}/projects # Add project tags
|
||||||
|
DELETE /api/items/{partNumber}/projects/{code} # Remove project tag
|
||||||
|
|
||||||
# Revisions
|
# Revisions
|
||||||
GET /api/items/{part_number}/revisions
|
GET /api/items/{partNumber}/revisions # List revisions
|
||||||
GET /api/items/{part_number}/revisions/{rev}
|
POST /api/items/{partNumber}/revisions # Create revision
|
||||||
|
GET /api/items/{partNumber}/revisions/compare # Compare two revisions
|
||||||
# Relationships
|
GET /api/items/{partNumber}/revisions/{revision} # Get specific revision
|
||||||
GET /api/items/{part_number}/bom
|
PATCH /api/items/{partNumber}/revisions/{revision} # Update status/labels
|
||||||
POST /api/items/{part_number}/relationships
|
POST /api/items/{partNumber}/revisions/{revision}/rollback # Rollback to revision
|
||||||
DELETE /api/items/{part_number}/relationships/{id}
|
|
||||||
|
|
||||||
# Files
|
# Files
|
||||||
GET /api/items/{part_number}/file
|
POST /api/items/{partNumber}/file # Upload file
|
||||||
PUT /api/items/{part_number}/file
|
GET /api/items/{partNumber}/file # Download latest file
|
||||||
GET /api/items/{part_number}/file?rev={rev}
|
GET /api/items/{partNumber}/file/{revision} # Download file at revision
|
||||||
|
|
||||||
# Schemas
|
# Part Number Generation
|
||||||
GET /api/schemas
|
POST /api/generate-part-number # Generate without creating item
|
||||||
POST /api/schemas
|
```
|
||||||
GET /api/schemas/{name}
|
|
||||||
|
|
||||||
# Locations
|
### 11.2 Not Yet Implemented
|
||||||
|
|
||||||
|
The following endpoints from the original design are not yet implemented:
|
||||||
|
|
||||||
|
```
|
||||||
|
# Locations (tables exist, no API)
|
||||||
GET /api/locations
|
GET /api/locations
|
||||||
POST /api/locations
|
POST /api/locations
|
||||||
GET /api/locations/{path}
|
GET /api/locations/{path}
|
||||||
|
|
||||||
# Inventory
|
# Inventory (tables exist, no API)
|
||||||
GET /api/inventory/{part_number}
|
GET /api/inventory/{partNumber}
|
||||||
POST /api/inventory/{part_number}/adjust
|
POST /api/inventory/{partNumber}/adjust
|
||||||
|
|
||||||
# Part number generation
|
|
||||||
POST /api/generate-part-number
|
|
||||||
Body: { "schema": "kindred-rd", "project": "PROTO", "part_type": "AS" }
|
|
||||||
Response: { "part_number": "PROTO-AS-0001" }
|
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 12. MVP Scope
|
## 12. MVP Scope
|
||||||
|
|
||||||
### 12.1 Included
|
### 12.1 Implemented
|
||||||
|
|
||||||
- [ ] PostgreSQL database schema
|
- [x] PostgreSQL database schema (7 migrations)
|
||||||
- [ ] YAML schema parser for part numbering
|
- [x] YAML schema parser for part numbering
|
||||||
- [ ] Part number generation engine
|
- [x] Part number generation engine
|
||||||
- [ ] Basic CLI for item CRUD
|
- [x] CLI tool (`cmd/silo`)
|
||||||
- [ ] FreeCAD workbench with core commands (checkout, commit, status, register)
|
- [x] API server (`cmd/silod`) with 35+ endpoints
|
||||||
- [ ] MinIO integration for file storage
|
- [x] FreeCAD workbench (save, commit, pull, push, info, register, open, browse)
|
||||||
- [ ] Single-level and multi-level BOM support
|
- [x] MinIO integration for file storage with versioning
|
||||||
- [ ] Reference designator tracking
|
- [x] BOM relationships (component, alternate, reference)
|
||||||
- [ ] Alternate part tracking
|
- [x] Reference designator tracking
|
||||||
- [ ] Revision history (append-only)
|
- [x] Revision history (append-only) with rollback and comparison
|
||||||
- [ ] Location hierarchy (YAML-defined)
|
- [x] Revision status and labels
|
||||||
- [ ] Basic inventory tracking (quantity at location)
|
- [x] Project management with many-to-many item tagging
|
||||||
- [ ] Web UI for browsing and search
|
- [x] CSV import/export with dry-run validation
|
||||||
- [ ] "Open in FreeCAD" URI handler
|
- [x] Web UI for items and schemas (htmx)
|
||||||
|
- [x] Property schema versioning framework
|
||||||
|
- [x] Docker Compose deployment (dev and prod)
|
||||||
|
- [x] systemd service and deployment scripts
|
||||||
|
|
||||||
### 12.2 Excluded (Future)
|
### 12.2 Partially Implemented
|
||||||
|
|
||||||
|
- [ ] Location hierarchy (database tables exist, no API endpoints)
|
||||||
|
- [ ] Inventory tracking (database tables exist, no API endpoints)
|
||||||
|
- [ ] Date segment type (schema parser placeholder only)
|
||||||
|
- [ ] Part number format validation on creation
|
||||||
|
|
||||||
|
### 12.3 Not Started
|
||||||
|
|
||||||
|
- [ ] Unit tests
|
||||||
- [ ] Schema migration tooling
|
- [ ] Schema migration tooling
|
||||||
- [ ] Multi-user with authentication
|
- [ ] Multi-user authentication (FreeIPA/LDAP planned)
|
||||||
- [ ] Checkout locking
|
- [ ] Checkout locking
|
||||||
- [ ] Approval workflows
|
- [ ] Approval workflows
|
||||||
- [ ] External system integrations (ERP, purchasing)
|
- [ ] External system integrations (ERP, purchasing)
|
||||||
@@ -649,7 +688,7 @@ POST /api/generate-part-number
|
|||||||
|
|
||||||
## 13. Open Questions
|
## 13. Open Questions
|
||||||
|
|
||||||
1. **CLI language**: Go for consistency with web UI, or Python for FreeCAD ecosystem alignment?
|
1. ~~**CLI language**: Go for consistency with web UI, or Python for FreeCAD ecosystem alignment?~~ **Resolved:** Go was chosen for both CLI and API server.
|
||||||
|
|
||||||
2. **Property schema**: Should item properties be schema-defined (like part numbers) or freeform? Recommendation: Support both—schema defines expected properties, but allow ad-hoc additions.
|
2. **Property schema**: Should item properties be schema-defined (like part numbers) or freeform? Recommendation: Support both—schema defines expected properties, but allow ad-hoc additions.
|
||||||
|
|
||||||
@@ -682,12 +721,14 @@ POST /api/generate-part-number
|
|||||||
|
|
||||||
### A.1 Complete Part Numbering Schema
|
### A.1 Complete Part Numbering Schema
|
||||||
|
|
||||||
|
See `schemas/kindred-rd.yaml` for the full schema (v3). Summary:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
# kindred-rd-schema.yaml
|
# kindred-rd-schema.yaml (abbreviated)
|
||||||
schema:
|
schema:
|
||||||
name: kindred-rd
|
name: kindred-rd
|
||||||
version: 1
|
version: 3
|
||||||
description: "Kindred Systems R&D part numbering for prototype development"
|
description: "Kindred Systems R&D part numbering"
|
||||||
|
|
||||||
separator: "-"
|
separator: "-"
|
||||||
|
|
||||||
@@ -696,50 +737,26 @@ schema:
|
|||||||
case_sensitive: false
|
case_sensitive: false
|
||||||
|
|
||||||
segments:
|
segments:
|
||||||
- name: project
|
- name: category
|
||||||
type: string
|
|
||||||
length: 5
|
|
||||||
case: upper
|
|
||||||
description: "5-character project identifier"
|
|
||||||
validation:
|
|
||||||
pattern: "^[A-Z0-9]{5}$"
|
|
||||||
message: "Project code must be exactly 5 alphanumeric characters"
|
|
||||||
required: true
|
|
||||||
|
|
||||||
- name: part_type
|
|
||||||
type: enum
|
type: enum
|
||||||
description: "Two-character type code"
|
description: "Category code"
|
||||||
required: true
|
required: true
|
||||||
values:
|
values:
|
||||||
AS: "Assembly - multi-part unit"
|
F01: "Hex Cap Screw"
|
||||||
PT: "Part - single manufactured item"
|
F02: "Socket Head Cap Screw"
|
||||||
DW: "Drawing - technical drawing"
|
# ... 70+ categories (see full file)
|
||||||
DC: "Document - specification, procedure, etc."
|
|
||||||
TB: "Tooling - jigs, fixtures, molds"
|
|
||||||
PC: "Purchased - externally sourced component"
|
|
||||||
EL: "Electrical - wiring, PCB, electronics"
|
|
||||||
SW: "Software - firmware, configuration"
|
|
||||||
|
|
||||||
- name: sequence
|
- name: sequence
|
||||||
type: serial
|
type: serial
|
||||||
length: 4
|
length: 4
|
||||||
padding: "0"
|
padding: "0"
|
||||||
start: 1
|
start: 1
|
||||||
description: "Sequential number within project/type"
|
description: "Sequential number within category"
|
||||||
scope: "{project}-{part_type}"
|
scope: "{category}"
|
||||||
|
|
||||||
format: "{project}-{part_type}-{sequence}"
|
format: "{category}-{sequence}"
|
||||||
|
|
||||||
# Validation rules applied to complete part number
|
# Example outputs: F01-0001, R27-0001, A01-0001
|
||||||
validation:
|
|
||||||
min_length: 14
|
|
||||||
max_length: 14
|
|
||||||
|
|
||||||
# Metadata for UI/documentation
|
|
||||||
examples:
|
|
||||||
- "PROTO-AS-0001"
|
|
||||||
- "ALPHA-PT-0042"
|
|
||||||
- "BETA1-EL-0003"
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### A.2 Complete Location Schema
|
### A.2 Complete Location Schema
|
||||||
|
|||||||
179
docs/STATUS.md
179
docs/STATUS.md
@@ -1,137 +1,92 @@
|
|||||||
# Silo Development Status
|
# Silo Development Status
|
||||||
|
|
||||||
**Date:** 2026-01-23
|
**Last Updated:** 2026-01-29
|
||||||
**Last Updated By:** Claude Code Session
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Current State: MinIO File Upload Implementation
|
## Implementation Status
|
||||||
|
|
||||||
### Completed Work
|
### Core Systems
|
||||||
|
|
||||||
#### 1. Docker Compose - MinIO Service Added
|
| Component | Status | Notes |
|
||||||
- File: `deployments/docker-compose.yaml`
|
|-----------|--------|-------|
|
||||||
- Added MinIO service with versioning enabled
|
| PostgreSQL schema | Complete | 7 migrations applied |
|
||||||
- Configured healthcheck and environment variables
|
| YAML schema parser | Complete | Supports enum, serial, constant, string segments |
|
||||||
- Note: Using `minio/minio:RELEASE.2024-01-16T16-07-38Z` for CPU compatibility
|
| Part number generator | Complete | Scoped sequences, category-based format |
|
||||||
|
| API server (`silod`) | Complete | 35+ REST endpoints via chi/v5 |
|
||||||
|
| CLI tool (`silo`) | Complete | Item registration and management |
|
||||||
|
| MinIO file storage | Complete | Upload, download, versioning, checksums |
|
||||||
|
| Revision control | Complete | Append-only history, rollback, comparison, status/labels |
|
||||||
|
| Project management | Complete | CRUD, many-to-many item tagging |
|
||||||
|
| CSV import/export | Complete | Dry-run validation, template generation |
|
||||||
|
| Web UI | Complete | Items and schemas pages (htmx) |
|
||||||
|
| Docker Compose | Complete | Dev and production configurations |
|
||||||
|
| Deployment scripts | Complete | setup-host, deploy, init-db, setup-ipa-nginx |
|
||||||
|
| systemd service | Complete | Unit file and environment template |
|
||||||
|
|
||||||
#### 2. API Endpoints - File Upload/Download
|
### FreeCAD Workbench
|
||||||
- File: `internal/api/handlers.go`
|
|
||||||
|
|
||||||
| Endpoint | Method | Description |
|
| Command | Status | Notes |
|
||||||
|----------|--------|-------------|
|
|---------|--------|-------|
|
||||||
| `/api/items/{partNumber}/file` | POST | Upload file and create revision |
|
| Silo_Save | Implemented | Auto-save + upload to MinIO |
|
||||||
| `/api/items/{partNumber}/file` | GET | Download latest revision file |
|
| Silo_Commit | Implemented | Save with revision comment |
|
||||||
| `/api/items/{partNumber}/file/{revision}` | GET | Download specific revision file |
|
| Silo_Pull | Implemented | Download / create items |
|
||||||
| `/api/items/{partNumber}/revisions` | POST | Create revision without file |
|
| Silo_Push | Implemented | Batch upload modified files |
|
||||||
|
| Silo_Info | Implemented | View revision history |
|
||||||
|
| Silo_Register | Implemented | Generate part number for document |
|
||||||
|
| Silo_Open | Implemented | Open item by part number |
|
||||||
|
| Silo_Browse | Implemented | Browse items in list dialog |
|
||||||
|
|
||||||
#### 3. Routes Added
|
Workbench needs end-to-end testing with a running Silo instance.
|
||||||
- File: `internal/api/routes.go`
|
|
||||||
- All new endpoints wired up
|
|
||||||
|
|
||||||
#### 4. FreeCAD Client Updated
|
### Not Yet Implemented
|
||||||
- File: `pkg/freecad/silo_commands.py`
|
|
||||||
- Added `_upload_file()` method for multipart form upload
|
|
||||||
- Updated `create_revision()` to optionally upload files
|
|
||||||
- Updated `Silo_Commit` command to save document and upload to MinIO
|
|
||||||
|
|
||||||
#### 5. Build Status
|
| Feature | Notes |
|
||||||
- **Go code compiles successfully** - `go build ./...` passes
|
|---------|-------|
|
||||||
|
| Location API endpoints | Database tables exist (`locations`, `inventory`), no REST handlers |
|
||||||
|
| Inventory API endpoints | Database tables exist, no REST handlers |
|
||||||
|
| Date segment type | Schema parser placeholder only |
|
||||||
|
| Part number format validation | API accepts but does not validate format on creation |
|
||||||
|
| Unit tests | No test coverage |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Where We Left Off
|
## Infrastructure
|
||||||
|
|
||||||
### Problem
|
| Service | Host | Status |
|
||||||
MinIO container failing to start due to CPU architecture:
|
|---------|------|--------|
|
||||||
```
|
| PostgreSQL | psql.kindred.internal:5432 | Running |
|
||||||
Fatal glibc error: CPU does not support x86-64-v2
|
| MinIO | localhost:9000 (API) / :9001 (console) | Configured |
|
||||||
```
|
| Silo API | localhost:8080 | Builds successfully |
|
||||||
|
|
||||||
### Solution in Progress
|
|
||||||
- VM being rebooted to newer architecture
|
|
||||||
- Already configured older MinIO image as fallback
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Next Steps After VM Reboot
|
## Schema Status
|
||||||
|
|
||||||
### 1. Start Services
|
The part numbering schema (`kindred-rd`) is at **version 3** using the `{category}-{sequence}` format (e.g., `F01-0001`). This replaced the earlier `{project}-{type}-{sequence}` format. Projects are now managed as many-to-many tags rather than being embedded in part numbers.
|
||||||
```bash
|
|
||||||
cd /home/forbes/projects/silo-0062/deployments
|
|
||||||
sudo docker compose up -d
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Verify Services
|
The schema defines 70+ categories across 10 groups:
|
||||||
```bash
|
- F01-F18: Fasteners
|
||||||
# Check all services
|
- C01-C17: Fluid Fittings
|
||||||
sudo docker compose ps
|
- R01-R44: Motion Components
|
||||||
|
- S01-S17: Structural Materials
|
||||||
# Check MinIO health
|
- E01-E27: Electrical Components
|
||||||
curl http://localhost:9000/minio/health/live
|
- M01-M18: Mechanical Components
|
||||||
|
- T01-T08: Tooling and Fixtures
|
||||||
# Check Silo API with storage
|
- A01-A07: Assemblies
|
||||||
curl http://localhost:8080/ready
|
- P01-P05: Purchased/Off-the-Shelf
|
||||||
```
|
- X01-X08: Custom Fabricated Parts
|
||||||
|
|
||||||
### 3. Test File Upload
|
|
||||||
```bash
|
|
||||||
# Create test file
|
|
||||||
echo "Test content" > /tmp/test.FCStd
|
|
||||||
|
|
||||||
# Upload to existing item
|
|
||||||
curl -X POST \
|
|
||||||
-F "file=@/tmp/test.FCStd" \
|
|
||||||
-F "comment=Test upload" \
|
|
||||||
-F 'properties={"test": true}' \
|
|
||||||
http://localhost:8080/api/items/3DX15-A01-0002/file
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4. Test File Download
|
|
||||||
```bash
|
|
||||||
# Download latest revision
|
|
||||||
curl http://localhost:8080/api/items/3DX15-A01-0002/file -o downloaded.FCStd
|
|
||||||
|
|
||||||
# Download specific revision
|
|
||||||
curl http://localhost:8080/api/items/3DX15-A01-0002/file/2 -o rev2.FCStd
|
|
||||||
```
|
|
||||||
|
|
||||||
### 5. Test from FreeCAD
|
|
||||||
1. Open FreeCAD with Silo workbench
|
|
||||||
2. Open an existing item: `Silo_Open` command
|
|
||||||
3. Make changes
|
|
||||||
4. Commit with file upload: `Silo_Commit` command
|
|
||||||
5. Verify file appears in MinIO console at http://localhost:9001
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Remaining MVP Tasks
|
## Database Migrations
|
||||||
|
|
||||||
| Task | Status | Priority |
|
| Migration | Description |
|
||||||
|------|--------|----------|
|
|-----------|-------------|
|
||||||
| Start docker-compose with MinIO | Pending | **Next** |
|
| 001_initial.sql | Core schema (items, revisions, relationships, locations, inventory, sequences) |
|
||||||
| Test full upload/download flow | Pending | High |
|
| 002_sequence_by_name.sql | Sequence naming changes |
|
||||||
| Implement date segment support | Pending | Medium |
|
| 003_remove_material.sql | Schema cleanup |
|
||||||
| Implement part number validation | Pending | Medium |
|
| 004_cad_sync_state.sql | CAD synchronization state |
|
||||||
| Add unit tests | Pending | Medium |
|
| 005_property_schema_version.sql | Property versioning framework |
|
||||||
|
| 006_project_tags.sql | Many-to-many project-item relationships |
|
||||||
---
|
| 007_revision_status.sql | Revision status and labels |
|
||||||
|
|
||||||
## File Changes This Session
|
|
||||||
|
|
||||||
```
|
|
||||||
modified: deployments/docker-compose.yaml (added MinIO service)
|
|
||||||
modified: internal/api/handlers.go (added file handlers)
|
|
||||||
modified: internal/api/routes.go (added file routes)
|
|
||||||
modified: pkg/freecad/silo_commands.py (added file upload)
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## MinIO Console Access
|
|
||||||
|
|
||||||
Once running:
|
|
||||||
- **URL:** http://localhost:9001
|
|
||||||
- **Username:** silominio
|
|
||||||
- **Password:** silominiosecret
|
|
||||||
- **Bucket:** silo-files
|
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
"""Silo FreeCAD Workbench - Item database integration."""
|
"""Kindred Silo Workbench - Item database integration for Kindred Create."""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
import FreeCAD
|
import FreeCAD
|
||||||
import FreeCADGui
|
import FreeCADGui
|
||||||
|
|
||||||
FreeCAD.Console.PrintMessage("Silo InitGui.py loading...\n")
|
FreeCAD.Console.PrintMessage("Kindred Silo InitGui.py loading...\n")
|
||||||
|
|
||||||
|
|
||||||
class SiloWorkbench(FreeCADGui.Workbench):
|
class SiloWorkbench(FreeCADGui.Workbench):
|
||||||
"""Silo workbench for item database integration."""
|
"""Kindred Silo workbench for item database integration."""
|
||||||
|
|
||||||
MenuText = "Silo"
|
MenuText = "Kindred Silo"
|
||||||
ToolTip = "Item database and part management"
|
ToolTip = "Item database and part management for Kindred Create"
|
||||||
Icon = ""
|
Icon = ""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@@ -54,7 +54,7 @@ class SiloWorkbench(FreeCADGui.Workbench):
|
|||||||
|
|
||||||
def Activated(self):
|
def Activated(self):
|
||||||
"""Called when workbench is activated."""
|
"""Called when workbench is activated."""
|
||||||
FreeCAD.Console.PrintMessage("Silo workbench activated\n")
|
FreeCAD.Console.PrintMessage("Kindred Silo workbench activated\n")
|
||||||
FreeCAD.Console.PrintMessage(
|
FreeCAD.Console.PrintMessage(
|
||||||
" API: SILO_API_URL (default: http://localhost:8080/api)\n"
|
" API: SILO_API_URL (default: http://localhost:8080/api)\n"
|
||||||
)
|
)
|
||||||
@@ -73,7 +73,7 @@ class SiloWorkbench(FreeCADGui.Workbench):
|
|||||||
"""Show keyboard shortcut recommendations dialog on first activation."""
|
"""Show keyboard shortcut recommendations dialog on first activation."""
|
||||||
try:
|
try:
|
||||||
param_group = FreeCAD.ParamGet(
|
param_group = FreeCAD.ParamGet(
|
||||||
"User parameter:BaseApp/Preferences/Mod/Silo"
|
"User parameter:BaseApp/Preferences/Mod/KindredSilo"
|
||||||
)
|
)
|
||||||
if param_group.GetBool("ShortcutsShown", False):
|
if param_group.GetBool("ShortcutsShown", False):
|
||||||
return
|
return
|
||||||
@@ -81,7 +81,7 @@ class SiloWorkbench(FreeCADGui.Workbench):
|
|||||||
|
|
||||||
from PySide import QtGui
|
from PySide import QtGui
|
||||||
|
|
||||||
msg = """<h3>Welcome to Silo Workbench!</h3>
|
msg = """<h3>Welcome to Kindred Silo!</h3>
|
||||||
<p>For the best experience, set up these keyboard shortcuts:</p>
|
<p>For the best experience, set up these keyboard shortcuts:</p>
|
||||||
<table style="margin: 10px 0;">
|
<table style="margin: 10px 0;">
|
||||||
<tr><td><b>Ctrl+O</b></td><td> - </td><td>Silo_Open (Search & Open)</td></tr>
|
<tr><td><b>Ctrl+O</b></td><td> - </td><td>Silo_Open (Search & Open)</td></tr>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<package format="1" xmlns="https://wiki.freecad.org/Package_Metadata">
|
<package format="1" xmlns="https://wiki.freecad.org/Package_Metadata">
|
||||||
<name>Silo</name>
|
<name>Kindred Silo</name>
|
||||||
<description>Item database and part management workbench</description>
|
<description>Item database and part management workbench for Kindred Create</description>
|
||||||
<version>0.1.0</version>
|
<version>0.1.0</version>
|
||||||
<maintainer email="info@kindredsystems.io">Kindred Systems</maintainer>
|
<maintainer email="info@kindredsystems.io">Kindred Systems</maintainer>
|
||||||
<license file="LICENSE">MIT</license>
|
<license file="LICENSE">MIT</license>
|
||||||
|
|||||||
834
silo-spec.md
834
silo-spec.md
@@ -1,833 +1 @@
|
|||||||
# Silo: Item Database and Part Management System for FreeCAD
|
This document has moved to [docs/SPECIFICATION.md](docs/SPECIFICATION.md).
|
||||||
|
|
||||||
**Version:** 0.1 Draft
|
|
||||||
**Date:** January 2026
|
|
||||||
**Author:** Kindred Systems LLC
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 1. Overview
|
|
||||||
|
|
||||||
Silo is an item database with configurable part number generation, designed for R&D-oriented workflows. It integrates with FreeCAD 1.0+ to provide git-like object management, revision tracking, and physical inventory location management.
|
|
||||||
|
|
||||||
### 1.1 Core Philosophy
|
|
||||||
|
|
||||||
Silo treats **part numbering schemas as configuration, not code**. Multiple numbering schemes can coexist, each defined in YAML. The system is schema-agnostic—it doesn't impose a particular part numbering philosophy (intelligent vs. non-intelligent numbers) but instead provides the machinery to implement whatever scheme the organization requires.
|
|
||||||
|
|
||||||
### 1.2 Key Principles
|
|
||||||
|
|
||||||
- **Items are the atomic unit**: Everything is an item (parts, assemblies, drawings, documents)
|
|
||||||
- **Schemas are mutable**: Part numbering schemas can evolve, though migration tooling is out of scope for MVP
|
|
||||||
- **Append-only history**: All parameter changes are recorded; item state is reconstructable at any point in time
|
|
||||||
- **Configuration over convention**: Hierarchies, relationships, and behaviors are YAML-defined
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 2. Architecture
|
|
||||||
|
|
||||||
### 2.1 Components
|
|
||||||
|
|
||||||
```
|
|
||||||
┌─────────────────────────────────────────────────────────────┐
|
|
||||||
│ FreeCAD 1.0+ │
|
|
||||||
│ ┌─────────────────────────────────────────────────────┐ │
|
|
||||||
│ │ Silo Workbench (Python) │ │
|
|
||||||
│ │ - silo checkout / commit / status / log │ │
|
|
||||||
│ │ - Part number generation │ │
|
|
||||||
│ │ - Property sync with FreeCAD objects │ │
|
|
||||||
│ └─────────────────────────────────────────────────────┘ │
|
|
||||||
└─────────────────────────────────────────────────────────────┘
|
|
||||||
│
|
|
||||||
▼
|
|
||||||
┌─────────────────────────────────────────────────────────────┐
|
|
||||||
│ Silo Core (CLI/Library) │
|
|
||||||
│ - Schema parsing and validation │
|
|
||||||
│ - Part number generation engine │
|
|
||||||
│ - Revision management │
|
|
||||||
│ - Relationship graph │
|
|
||||||
└─────────────────────────────────────────────────────────────┘
|
|
||||||
│
|
|
||||||
┌───────────────┴───────────────┐
|
|
||||||
▼ ▼
|
|
||||||
┌─────────────────────────┐ ┌─────────────────────────────┐
|
|
||||||
│ PostgreSQL │ │ MinIO │
|
|
||||||
│ (psql.kindred.internal)│ │ - .FCStd file storage │
|
|
||||||
│ - Item metadata │ │ - Versioned objects │
|
|
||||||
│ - Relationships │ │ - Thumbnails │
|
|
||||||
│ - Revision history │ │ │
|
|
||||||
│ - Location hierarchy │ │ │
|
|
||||||
└─────────────────────────┘ └─────────────────────────────┘
|
|
||||||
│
|
|
||||||
▼
|
|
||||||
┌─────────────────────────────────────────────────────────────┐
|
|
||||||
│ Web UI (Browse/Search) │
|
|
||||||
│ - Item browser with hierarchy navigation │
|
|
||||||
│ - Search and filtering │
|
|
||||||
│ - "Open in FreeCAD" links (freecad:// URI handler) │
|
|
||||||
│ - BOM viewer │
|
|
||||||
└─────────────────────────────────────────────────────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2.2 Technology Stack
|
|
||||||
|
|
||||||
| Component | Technology | Notes |
|
|
||||||
|-----------|------------|-------|
|
|
||||||
| Database | PostgreSQL | Existing instance at psql.kindred.internal |
|
|
||||||
| File Storage | MinIO | S3-compatible, versioning enabled |
|
|
||||||
| FreeCAD Integration | Python workbench | Macro-style commands |
|
|
||||||
| CLI | Go or Python | TBD based on complexity |
|
|
||||||
| Web UI | Go + htmx | Lightweight, minimal JS |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 3. Data Model
|
|
||||||
|
|
||||||
### 3.1 Items
|
|
||||||
|
|
||||||
An **item** is the fundamental entity. Items have:
|
|
||||||
|
|
||||||
- A **part number** (generated according to a schema)
|
|
||||||
- A **type** (part, assembly, drawing, document, etc.)
|
|
||||||
- **Properties** (key-value pairs, schema-defined and custom)
|
|
||||||
- **Relationships** to other items
|
|
||||||
- **Revisions** (append-only history)
|
|
||||||
- **Files** (optional, stored in MinIO)
|
|
||||||
- **Location** (optional physical inventory location)
|
|
||||||
|
|
||||||
### 3.2 Database Schema (Conceptual)
|
|
||||||
|
|
||||||
```sql
|
|
||||||
-- Part numbering schemas (YAML stored as text, parsed at runtime)
|
|
||||||
CREATE TABLE schemas (
|
|
||||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
||||||
name TEXT UNIQUE NOT NULL,
|
|
||||||
version INTEGER NOT NULL DEFAULT 1,
|
|
||||||
definition JSONB NOT NULL, -- parsed YAML
|
|
||||||
created_at TIMESTAMPTZ DEFAULT now(),
|
|
||||||
updated_at TIMESTAMPTZ DEFAULT now()
|
|
||||||
);
|
|
||||||
|
|
||||||
-- Items (core entity)
|
|
||||||
CREATE TABLE items (
|
|
||||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
||||||
part_number TEXT UNIQUE NOT NULL,
|
|
||||||
schema_id UUID REFERENCES schemas(id),
|
|
||||||
item_type TEXT NOT NULL, -- 'part', 'assembly', 'drawing', etc.
|
|
||||||
created_at TIMESTAMPTZ DEFAULT now(),
|
|
||||||
current_revision_id UUID -- points to latest revision
|
|
||||||
);
|
|
||||||
|
|
||||||
-- Append-only revision history
|
|
||||||
CREATE TABLE revisions (
|
|
||||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
||||||
item_id UUID REFERENCES items(id) NOT NULL,
|
|
||||||
revision_number INTEGER NOT NULL,
|
|
||||||
properties JSONB NOT NULL, -- all properties at this revision
|
|
||||||
file_version TEXT, -- MinIO version ID if applicable
|
|
||||||
created_at TIMESTAMPTZ DEFAULT now(),
|
|
||||||
created_by TEXT, -- user identifier (future: LDAP DN)
|
|
||||||
comment TEXT,
|
|
||||||
UNIQUE(item_id, revision_number)
|
|
||||||
);
|
|
||||||
|
|
||||||
-- Item relationships (BOM structure)
|
|
||||||
CREATE TABLE relationships (
|
|
||||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
||||||
parent_item_id UUID REFERENCES items(id) NOT NULL,
|
|
||||||
child_item_id UUID REFERENCES items(id) NOT NULL,
|
|
||||||
relationship_type TEXT NOT NULL, -- 'component', 'alternate', 'reference'
|
|
||||||
quantity DECIMAL,
|
|
||||||
reference_designator TEXT, -- e.g., "R1", "C3" for electronics
|
|
||||||
metadata JSONB, -- assembly-specific relationship config
|
|
||||||
revision_id UUID REFERENCES revisions(id), -- which revision this applies to
|
|
||||||
created_at TIMESTAMPTZ DEFAULT now()
|
|
||||||
);
|
|
||||||
|
|
||||||
-- Location hierarchy (configurable via YAML)
|
|
||||||
CREATE TABLE locations (
|
|
||||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
||||||
path TEXT UNIQUE NOT NULL, -- e.g., "lab/shelf-a/bin-3"
|
|
||||||
name TEXT NOT NULL,
|
|
||||||
parent_id UUID REFERENCES locations(id),
|
|
||||||
location_type TEXT NOT NULL, -- defined in location schema
|
|
||||||
metadata JSONB,
|
|
||||||
created_at TIMESTAMPTZ DEFAULT now()
|
|
||||||
);
|
|
||||||
|
|
||||||
-- Item inventory (quantity at location)
|
|
||||||
CREATE TABLE inventory (
|
|
||||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
||||||
item_id UUID REFERENCES items(id) NOT NULL,
|
|
||||||
location_id UUID REFERENCES locations(id) NOT NULL,
|
|
||||||
quantity DECIMAL NOT NULL DEFAULT 0,
|
|
||||||
updated_at TIMESTAMPTZ DEFAULT now(),
|
|
||||||
UNIQUE(item_id, location_id)
|
|
||||||
);
|
|
||||||
|
|
||||||
-- Sequence counters for part number generation
|
|
||||||
CREATE TABLE sequences (
|
|
||||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
||||||
schema_id UUID REFERENCES schemas(id),
|
|
||||||
scope TEXT NOT NULL, -- scope key (e.g., project code, type code)
|
|
||||||
current_value INTEGER NOT NULL DEFAULT 0,
|
|
||||||
UNIQUE(schema_id, scope)
|
|
||||||
);
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 4. YAML Configuration System
|
|
||||||
|
|
||||||
### 4.1 Part Numbering Schema
|
|
||||||
|
|
||||||
Schemas define how part numbers are generated. Each schema consists of **segments** that are concatenated with a **separator**.
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
# /etc/silo/schemas/kindred-rd.yaml
|
|
||||||
schema:
|
|
||||||
name: kindred-rd
|
|
||||||
version: 1
|
|
||||||
description: "Kindred Systems R&D part numbering"
|
|
||||||
|
|
||||||
# Separator between segments (default: "-")
|
|
||||||
separator: "-"
|
|
||||||
|
|
||||||
# Uniqueness enforcement
|
|
||||||
uniqueness:
|
|
||||||
scope: global # or "per-project", "per-type", "per-schema"
|
|
||||||
|
|
||||||
segments:
|
|
||||||
- name: project
|
|
||||||
type: string
|
|
||||||
length: 5
|
|
||||||
description: "Project identifier"
|
|
||||||
validation:
|
|
||||||
pattern: "^[A-Z0-9]{5}$"
|
|
||||||
required: true
|
|
||||||
|
|
||||||
- name: part_type
|
|
||||||
type: enum
|
|
||||||
description: "Type of item"
|
|
||||||
values:
|
|
||||||
AS: "Assembly"
|
|
||||||
PT: "Part"
|
|
||||||
DW: "Drawing"
|
|
||||||
DC: "Document"
|
|
||||||
TB: "Tooling/Fixture"
|
|
||||||
PC: "Purchased Component"
|
|
||||||
required: true
|
|
||||||
|
|
||||||
- name: sequence
|
|
||||||
type: serial
|
|
||||||
length: 4
|
|
||||||
padding: "0" # left-pad with zeros
|
|
||||||
description: "Sequential number"
|
|
||||||
scope: "{project}-{part_type}" # counter scope (template)
|
|
||||||
|
|
||||||
# Format template (optional, defaults to joining segments with separator)
|
|
||||||
format: "{project}-{part_type}-{sequence}"
|
|
||||||
|
|
||||||
# Example outputs:
|
|
||||||
# PROTO-AS-0001 (first assembly in PROTO project)
|
|
||||||
# PROTO-PT-0001 (first part in PROTO project)
|
|
||||||
# ALPHA-AS-0001 (first assembly in ALPHA project)
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4.2 Segment Types
|
|
||||||
|
|
||||||
| Type | Description | Options |
|
|
||||||
|------|-------------|---------|
|
|
||||||
| `string` | Fixed or variable length string | `length`, `min_length`, `max_length`, `pattern`, `case` |
|
|
||||||
| `enum` | Predefined set of values | `values` (map of code → description) |
|
|
||||||
| `serial` | Auto-incrementing integer | `length`, `padding`, `start`, `scope` |
|
|
||||||
| `date` | Date-based segment | `format` (strftime-style) |
|
|
||||||
| `constant` | Fixed value | `value` |
|
|
||||||
|
|
||||||
### 4.3 Serial Scope Templates
|
|
||||||
|
|
||||||
The `scope` field in serial segments supports template variables referencing other segments:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
# Sequence per project
|
|
||||||
scope: "{project}"
|
|
||||||
|
|
||||||
# Sequence per project AND type (recommended for R&D)
|
|
||||||
scope: "{project}-{part_type}"
|
|
||||||
|
|
||||||
# Global sequence (no scope)
|
|
||||||
scope: null
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4.4 Alternative Schema Example (Simple Sequential)
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
# /etc/silo/schemas/simple.yaml
|
|
||||||
schema:
|
|
||||||
name: simple
|
|
||||||
version: 1
|
|
||||||
description: "Simple non-intelligent numbering"
|
|
||||||
|
|
||||||
segments:
|
|
||||||
- name: prefix
|
|
||||||
type: constant
|
|
||||||
value: "P"
|
|
||||||
|
|
||||||
- name: sequence
|
|
||||||
type: serial
|
|
||||||
length: 6
|
|
||||||
padding: "0"
|
|
||||||
scope: null # global counter
|
|
||||||
|
|
||||||
format: "{prefix}{sequence}"
|
|
||||||
separator: ""
|
|
||||||
|
|
||||||
# Output: P000001, P000002, ...
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4.5 Location Hierarchy Schema
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
# /etc/silo/schemas/locations.yaml
|
|
||||||
location_schema:
|
|
||||||
name: kindred-lab
|
|
||||||
version: 1
|
|
||||||
|
|
||||||
hierarchy:
|
|
||||||
- level: 0
|
|
||||||
type: facility
|
|
||||||
name_pattern: "^[a-z-]+$"
|
|
||||||
|
|
||||||
- level: 1
|
|
||||||
type: area
|
|
||||||
name_pattern: "^[a-z-]+$"
|
|
||||||
|
|
||||||
- level: 2
|
|
||||||
type: shelf
|
|
||||||
name_pattern: "^shelf-[a-z]$"
|
|
||||||
|
|
||||||
- level: 3
|
|
||||||
type: bin
|
|
||||||
name_pattern: "^bin-[0-9]+$"
|
|
||||||
|
|
||||||
# Path format
|
|
||||||
path_separator: "/"
|
|
||||||
|
|
||||||
# Example paths:
|
|
||||||
# lab/main-area/shelf-a/bin-1
|
|
||||||
# lab/storage/shelf-b/bin-12
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4.6 Assembly Metadata Schema
|
|
||||||
|
|
||||||
Each assembly can define its own relationship tracking behavior:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
# Stored in item properties or as a linked document
|
|
||||||
assembly_config:
|
|
||||||
# What relationship types this assembly uses
|
|
||||||
relationship_types:
|
|
||||||
- component # standard BOM entry
|
|
||||||
- alternate # interchangeable substitute
|
|
||||||
- reference # related but not part of BOM
|
|
||||||
|
|
||||||
# Whether to track reference designators
|
|
||||||
use_reference_designators: true
|
|
||||||
designator_format: "^[A-Z]+[0-9]+$" # e.g., R1, C3, U12
|
|
||||||
|
|
||||||
# Revision linking behavior
|
|
||||||
child_revision_tracking: specific # or "latest"
|
|
||||||
|
|
||||||
# Custom properties for relationships
|
|
||||||
relationship_properties:
|
|
||||||
- name: mounting_orientation
|
|
||||||
type: enum
|
|
||||||
values: [top, bottom, left, right, front, back]
|
|
||||||
- name: notes
|
|
||||||
type: text
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 5. FreeCAD Integration
|
|
||||||
|
|
||||||
### 5.1 Workbench Commands
|
|
||||||
|
|
||||||
The Silo workbench provides git-like commands accessible via toolbar, menu, and Python console:
|
|
||||||
|
|
||||||
| Command | Description |
|
|
||||||
|---------|-------------|
|
|
||||||
| `silo init` | Initialize Silo tracking for current document |
|
|
||||||
| `silo status` | Show tracked/untracked objects, modifications |
|
|
||||||
| `silo checkout <part_number>` | Load item from Silo into current document |
|
|
||||||
| `silo commit` | Save current state as new revision |
|
|
||||||
| `silo log` | Show revision history |
|
|
||||||
| `silo diff` | Compare current state to last committed revision |
|
|
||||||
| `silo register` | Generate part number for selected object(s) |
|
|
||||||
| `silo link` | Create relationship between objects |
|
|
||||||
| `silo bom` | Generate BOM from current assembly |
|
|
||||||
|
|
||||||
### 5.2 Property Synchronization
|
|
||||||
|
|
||||||
Silo properties map to FreeCAD custom properties:
|
|
||||||
|
|
||||||
```python
|
|
||||||
# FreeCAD object properties (synced from Silo)
|
|
||||||
obj.addProperty("App::PropertyString", "SiloPartNumber", "Silo", "Part number")
|
|
||||||
obj.addProperty("App::PropertyString", "SiloRevision", "Silo", "Current revision")
|
|
||||||
obj.addProperty("App::PropertyString", "SiloDescription", "Silo", "Item description")
|
|
||||||
# ... additional properties as defined in schema
|
|
||||||
```
|
|
||||||
|
|
||||||
### 5.3 File Storage Strategy
|
|
||||||
|
|
||||||
FreeCAD `.FCStd` files are ZIP archives. Storage options:
|
|
||||||
|
|
||||||
1. **Whole file storage** (MVP): Store complete .FCStd in MinIO with versioning
|
|
||||||
2. **Exploded storage** (future): Unpack and store components separately for better diffing
|
|
||||||
|
|
||||||
For MVP, whole file storage is simpler and MinIO versioning handles history.
|
|
||||||
|
|
||||||
### 5.4 Checkout Locking (Future)
|
|
||||||
|
|
||||||
MVP operates as single-user. Future multi-user support will need locking strategy:
|
|
||||||
|
|
||||||
- **Pessimistic locking**: Checkout acquires exclusive lock
|
|
||||||
- **Optimistic locking**: Allow concurrent edits, handle conflicts on commit
|
|
||||||
|
|
||||||
Recommendation for future: Pessimistic locking for CAD files (merge is impractical).
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 6. Web Interface
|
|
||||||
|
|
||||||
### 6.1 Features
|
|
||||||
|
|
||||||
- **Browse**: Navigate item hierarchy (project → assembly → subassembly → part)
|
|
||||||
- **Search**: Full-text search across part numbers, descriptions, properties
|
|
||||||
- **View**: Item details, revision history, relationships, location
|
|
||||||
- **BOM Viewer**: Expandable tree view of assembly structure
|
|
||||||
- **"Open in FreeCAD"**: Launch FreeCAD with specific item via URI handler
|
|
||||||
|
|
||||||
### 6.2 URI Handler
|
|
||||||
|
|
||||||
Register `silo://` protocol handler:
|
|
||||||
|
|
||||||
```
|
|
||||||
silo://open/PROTO-AS-0001 # Open latest revision
|
|
||||||
silo://open/PROTO-AS-0001?rev=3 # Open specific revision
|
|
||||||
```
|
|
||||||
|
|
||||||
### 6.3 Technology
|
|
||||||
|
|
||||||
- **Backend**: Go with standard library HTTP
|
|
||||||
- **Frontend**: htmx for interactivity, minimal JavaScript
|
|
||||||
- **Templates**: Go html/template
|
|
||||||
- **Search**: PostgreSQL full-text search (pg_trgm for fuzzy matching)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 7. Revision Tracking
|
|
||||||
|
|
||||||
### 7.1 Append-Only Model
|
|
||||||
|
|
||||||
Every property change creates a new revision record. The current state is always the latest revision, but any historical state can be reconstructed.
|
|
||||||
|
|
||||||
```
|
|
||||||
Item: PROTO-AS-0001
|
|
||||||
|
|
||||||
Revision 1 (2026-01-15): Initial creation
|
|
||||||
- description: "Main chassis assembly"
|
|
||||||
- material: null
|
|
||||||
- weight: null
|
|
||||||
|
|
||||||
Revision 2 (2026-01-20): Updated properties
|
|
||||||
- description: "Main chassis assembly"
|
|
||||||
- material: "6061-T6 Aluminum"
|
|
||||||
- weight: 2.5
|
|
||||||
|
|
||||||
Revision 3 (2026-02-01): Design change
|
|
||||||
- description: "Main chassis assembly v2"
|
|
||||||
- material: "6061-T6 Aluminum"
|
|
||||||
- weight: 2.3
|
|
||||||
```
|
|
||||||
|
|
||||||
### 7.2 Revision Creation
|
|
||||||
|
|
||||||
Revisions are created explicitly by user action (not automatic):
|
|
||||||
|
|
||||||
- `silo commit` from FreeCAD
|
|
||||||
- "Save Revision" button in web UI
|
|
||||||
- API call with explicit revision flag
|
|
||||||
|
|
||||||
### 7.3 Revision vs. File Version
|
|
||||||
|
|
||||||
- **Revision**: Silo metadata revision (tracked in PostgreSQL)
|
|
||||||
- **File Version**: MinIO object version (automatic on upload)
|
|
||||||
|
|
||||||
A single Silo revision may span multiple file uploads during editing. Only committed revisions create formal revision records.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 8. Relationships and BOM
|
|
||||||
|
|
||||||
### 8.1 Relationship Types
|
|
||||||
|
|
||||||
| Type | Description | Use Case |
|
|
||||||
|------|-------------|----------|
|
|
||||||
| `component` | Part is used in assembly | Standard BOM entry |
|
|
||||||
| `alternate` | Interchangeable substitute | Alternative sourcing |
|
|
||||||
| `reference` | Related item, not in BOM | Drawings, specs, tools |
|
|
||||||
|
|
||||||
### 8.2 Reference Designators
|
|
||||||
|
|
||||||
For assemblies that require them (electronics, complex mechanisms):
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
# Relationship record
|
|
||||||
parent: PROTO-AS-0001
|
|
||||||
child: PROTO-PT-0042
|
|
||||||
type: component
|
|
||||||
quantity: 4
|
|
||||||
reference_designators: ["R1", "R2", "R3", "R4"]
|
|
||||||
```
|
|
||||||
|
|
||||||
### 8.3 Revision-Specific Relationships
|
|
||||||
|
|
||||||
Relationships can link to specific child revisions or track latest:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
# Locked to specific revision
|
|
||||||
child: PROTO-PT-0042
|
|
||||||
child_revision: 3
|
|
||||||
|
|
||||||
# Always use latest (default for R&D)
|
|
||||||
child: PROTO-PT-0042
|
|
||||||
child_revision: null # means "latest"
|
|
||||||
```
|
|
||||||
|
|
||||||
Assembly metadata YAML controls default behavior per assembly.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 9. Physical Inventory
|
|
||||||
|
|
||||||
### 9.1 Location Management
|
|
||||||
|
|
||||||
Locations are hierarchical, defined by YAML schema. Each item can exist at multiple locations with quantities.
|
|
||||||
|
|
||||||
```
|
|
||||||
Location: lab/main-area/shelf-a/bin-3
|
|
||||||
- PROTO-PT-0001: 15 units
|
|
||||||
- PROTO-PT-0002: 8 units
|
|
||||||
|
|
||||||
Location: lab/storage/shelf-b/bin-1
|
|
||||||
- PROTO-PT-0001: 50 units (spare stock)
|
|
||||||
```
|
|
||||||
|
|
||||||
### 9.2 Inventory Operations
|
|
||||||
|
|
||||||
- **Add**: Increase quantity at location
|
|
||||||
- **Remove**: Decrease quantity at location
|
|
||||||
- **Move**: Transfer between locations
|
|
||||||
- **Adjust**: Set absolute quantity (for cycle counts)
|
|
||||||
|
|
||||||
All operations logged for audit trail (future consideration).
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 10. Authentication (Future)
|
|
||||||
|
|
||||||
### 10.1 Current State (MVP)
|
|
||||||
|
|
||||||
Single-user, no authentication required.
|
|
||||||
|
|
||||||
### 10.2 Future: LDAPS Integration
|
|
||||||
|
|
||||||
Plan for FreeIPA integration:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
# /etc/silo/auth.yaml
|
|
||||||
auth:
|
|
||||||
provider: ldap
|
|
||||||
server: ldaps://ipa.kindred.internal
|
|
||||||
base_dn: "dc=kindred,dc=internal"
|
|
||||||
user_dn_template: "uid={username},cn=users,cn=accounts,dc=kindred,dc=internal"
|
|
||||||
group_base: "cn=groups,cn=accounts,dc=kindred,dc=internal"
|
|
||||||
|
|
||||||
# Role mapping
|
|
||||||
roles:
|
|
||||||
admin:
|
|
||||||
groups: ["silo-admins"]
|
|
||||||
editor:
|
|
||||||
groups: ["silo-users", "engineers"]
|
|
||||||
viewer:
|
|
||||||
groups: ["silo-viewers"]
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 11. API Design (Sketch)
|
|
||||||
|
|
||||||
### 11.1 REST Endpoints
|
|
||||||
|
|
||||||
```
|
|
||||||
# Items
|
|
||||||
GET /api/items # List/search items
|
|
||||||
POST /api/items # Create item
|
|
||||||
GET /api/items/{part_number} # Get item details
|
|
||||||
PUT /api/items/{part_number} # Update item (creates revision)
|
|
||||||
DELETE /api/items/{part_number} # Archive item
|
|
||||||
|
|
||||||
# Revisions
|
|
||||||
GET /api/items/{part_number}/revisions
|
|
||||||
GET /api/items/{part_number}/revisions/{rev}
|
|
||||||
|
|
||||||
# Relationships
|
|
||||||
GET /api/items/{part_number}/bom
|
|
||||||
POST /api/items/{part_number}/relationships
|
|
||||||
DELETE /api/items/{part_number}/relationships/{id}
|
|
||||||
|
|
||||||
# Files
|
|
||||||
GET /api/items/{part_number}/file
|
|
||||||
PUT /api/items/{part_number}/file
|
|
||||||
GET /api/items/{part_number}/file?rev={rev}
|
|
||||||
|
|
||||||
# Schemas
|
|
||||||
GET /api/schemas
|
|
||||||
POST /api/schemas
|
|
||||||
GET /api/schemas/{name}
|
|
||||||
|
|
||||||
# Locations
|
|
||||||
GET /api/locations
|
|
||||||
POST /api/locations
|
|
||||||
GET /api/locations/{path}
|
|
||||||
|
|
||||||
# Inventory
|
|
||||||
GET /api/inventory/{part_number}
|
|
||||||
POST /api/inventory/{part_number}/adjust
|
|
||||||
|
|
||||||
# Part number generation
|
|
||||||
POST /api/generate-part-number
|
|
||||||
Body: { "schema": "kindred-rd", "project": "PROTO", "part_type": "AS" }
|
|
||||||
Response: { "part_number": "PROTO-AS-0001" }
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 12. MVP Scope
|
|
||||||
|
|
||||||
### 12.1 Included
|
|
||||||
|
|
||||||
- [ ] PostgreSQL database schema
|
|
||||||
- [ ] YAML schema parser for part numbering
|
|
||||||
- [ ] Part number generation engine
|
|
||||||
- [ ] Basic CLI for item CRUD
|
|
||||||
- [ ] FreeCAD workbench with core commands (checkout, commit, status, register)
|
|
||||||
- [ ] MinIO integration for file storage
|
|
||||||
- [ ] Single-level and multi-level BOM support
|
|
||||||
- [ ] Reference designator tracking
|
|
||||||
- [ ] Alternate part tracking
|
|
||||||
- [ ] Revision history (append-only)
|
|
||||||
- [ ] Location hierarchy (YAML-defined)
|
|
||||||
- [ ] Basic inventory tracking (quantity at location)
|
|
||||||
- [ ] Web UI for browsing and search
|
|
||||||
- [ ] "Open in FreeCAD" URI handler
|
|
||||||
|
|
||||||
### 12.2 Excluded (Future)
|
|
||||||
|
|
||||||
- [ ] Schema migration tooling
|
|
||||||
- [ ] Multi-user with authentication
|
|
||||||
- [ ] Checkout locking
|
|
||||||
- [ ] Approval workflows
|
|
||||||
- [ ] External system integrations (ERP, purchasing)
|
|
||||||
- [ ] Exploded file storage with diffing
|
|
||||||
- [ ] Audit logging
|
|
||||||
- [ ] Notifications
|
|
||||||
- [ ] Reporting/analytics
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 13. Open Questions
|
|
||||||
|
|
||||||
1. **CLI language**: Go for consistency with web UI, or Python for FreeCAD ecosystem alignment?
|
|
||||||
|
|
||||||
2. **Property schema**: Should item properties be schema-defined (like part numbers) or freeform? Recommendation: Support both—schema defines expected properties, but allow ad-hoc additions.
|
|
||||||
|
|
||||||
3. **Thumbnail generation**: Generate thumbnails from .FCStd on commit? Useful for web UI browsing.
|
|
||||||
|
|
||||||
4. **Search indexing**: PostgreSQL full-text search sufficient, or add dedicated search (Meilisearch, etc.)?
|
|
||||||
|
|
||||||
5. **Offline operation**: Should FreeCAD workbench support offline mode with sync? Adds significant complexity.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 14. References
|
|
||||||
|
|
||||||
### 14.1 Design Influences
|
|
||||||
|
|
||||||
- **CycloneDX BOM specification**: JSON/YAML schema patterns for component identification, relationships, and metadata (https://cyclonedx.org)
|
|
||||||
- **OpenBOM data model**: Reference-instance separation, flexible property schemas
|
|
||||||
- **FreeCAD DynamicData workbench**: Custom property patterns in FreeCAD
|
|
||||||
- **Ansible inventory YAML**: Hierarchical configuration patterns with variable inheritance
|
|
||||||
|
|
||||||
### 14.2 Related Standards
|
|
||||||
|
|
||||||
- **ISO 10303 (STEP)**: Product data representation
|
|
||||||
- **IPC-2581**: Electronics assembly BOM format
|
|
||||||
- **Package URL (PURL)**: Standardized component identification
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Appendix A: Example YAML Files
|
|
||||||
|
|
||||||
### A.1 Complete Part Numbering Schema
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
# kindred-rd-schema.yaml
|
|
||||||
schema:
|
|
||||||
name: kindred-rd
|
|
||||||
version: 1
|
|
||||||
description: "Kindred Systems R&D part numbering for prototype development"
|
|
||||||
|
|
||||||
separator: "-"
|
|
||||||
|
|
||||||
uniqueness:
|
|
||||||
scope: global
|
|
||||||
case_sensitive: false
|
|
||||||
|
|
||||||
segments:
|
|
||||||
- name: project
|
|
||||||
type: string
|
|
||||||
length: 5
|
|
||||||
case: upper
|
|
||||||
description: "5-character project identifier"
|
|
||||||
validation:
|
|
||||||
pattern: "^[A-Z0-9]{5}$"
|
|
||||||
message: "Project code must be exactly 5 alphanumeric characters"
|
|
||||||
required: true
|
|
||||||
|
|
||||||
- name: part_type
|
|
||||||
type: enum
|
|
||||||
description: "Two-character type code"
|
|
||||||
required: true
|
|
||||||
values:
|
|
||||||
AS: "Assembly - multi-part unit"
|
|
||||||
PT: "Part - single manufactured item"
|
|
||||||
DW: "Drawing - technical drawing"
|
|
||||||
DC: "Document - specification, procedure, etc."
|
|
||||||
TB: "Tooling - jigs, fixtures, molds"
|
|
||||||
PC: "Purchased - externally sourced component"
|
|
||||||
EL: "Electrical - wiring, PCB, electronics"
|
|
||||||
SW: "Software - firmware, configuration"
|
|
||||||
|
|
||||||
- name: sequence
|
|
||||||
type: serial
|
|
||||||
length: 4
|
|
||||||
padding: "0"
|
|
||||||
start: 1
|
|
||||||
description: "Sequential number within project/type"
|
|
||||||
scope: "{project}-{part_type}"
|
|
||||||
|
|
||||||
format: "{project}-{part_type}-{sequence}"
|
|
||||||
|
|
||||||
# Validation rules applied to complete part number
|
|
||||||
validation:
|
|
||||||
min_length: 14
|
|
||||||
max_length: 14
|
|
||||||
|
|
||||||
# Metadata for UI/documentation
|
|
||||||
examples:
|
|
||||||
- "PROTO-AS-0001"
|
|
||||||
- "ALPHA-PT-0042"
|
|
||||||
- "BETA1-EL-0003"
|
|
||||||
```
|
|
||||||
|
|
||||||
### A.2 Complete Location Schema
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
# kindred-locations.yaml
|
|
||||||
location_schema:
|
|
||||||
name: kindred-lab
|
|
||||||
version: 1
|
|
||||||
description: "Kindred Systems lab and storage locations"
|
|
||||||
|
|
||||||
path_separator: "/"
|
|
||||||
|
|
||||||
hierarchy:
|
|
||||||
- level: 0
|
|
||||||
type: facility
|
|
||||||
description: "Building or site"
|
|
||||||
name_pattern: "^[a-z][a-z0-9-]*$"
|
|
||||||
examples: ["lab", "warehouse", "office"]
|
|
||||||
|
|
||||||
- level: 1
|
|
||||||
type: area
|
|
||||||
description: "Room or zone within facility"
|
|
||||||
name_pattern: "^[a-z][a-z0-9-]*$"
|
|
||||||
examples: ["main-lab", "storage", "assembly"]
|
|
||||||
|
|
||||||
- level: 2
|
|
||||||
type: shelf
|
|
||||||
description: "Shelving unit"
|
|
||||||
name_pattern: "^shelf-[a-z]$"
|
|
||||||
examples: ["shelf-a", "shelf-b"]
|
|
||||||
|
|
||||||
- level: 3
|
|
||||||
type: bin
|
|
||||||
description: "Individual container or bin"
|
|
||||||
name_pattern: "^bin-[0-9]{1,3}$"
|
|
||||||
examples: ["bin-1", "bin-42", "bin-100"]
|
|
||||||
|
|
||||||
# Properties tracked per location type
|
|
||||||
properties:
|
|
||||||
facility:
|
|
||||||
- name: address
|
|
||||||
type: text
|
|
||||||
required: false
|
|
||||||
area:
|
|
||||||
- name: climate_controlled
|
|
||||||
type: boolean
|
|
||||||
default: false
|
|
||||||
shelf:
|
|
||||||
- name: max_weight_kg
|
|
||||||
type: number
|
|
||||||
required: false
|
|
||||||
bin:
|
|
||||||
- name: bin_size
|
|
||||||
type: enum
|
|
||||||
values: [small, medium, large]
|
|
||||||
default: medium
|
|
||||||
```
|
|
||||||
|
|
||||||
### A.3 Assembly Configuration
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
# Stored as item property or linked document
|
|
||||||
# Example: assembly PROTO-AS-0001
|
|
||||||
assembly_config:
|
|
||||||
name: "Main Chassis Assembly"
|
|
||||||
|
|
||||||
relationship_types:
|
|
||||||
- component
|
|
||||||
- alternate
|
|
||||||
- reference
|
|
||||||
|
|
||||||
use_reference_designators: false
|
|
||||||
|
|
||||||
child_revision_tracking: latest
|
|
||||||
|
|
||||||
# Assembly-specific BOM properties
|
|
||||||
relationship_properties:
|
|
||||||
- name: installation_notes
|
|
||||||
type: text
|
|
||||||
- name: torque_spec
|
|
||||||
type: text
|
|
||||||
- name: adhesive_required
|
|
||||||
type: boolean
|
|
||||||
default: false
|
|
||||||
|
|
||||||
# Validation rules
|
|
||||||
validation:
|
|
||||||
require_quantity: true
|
|
||||||
min_components: 1
|
|
||||||
```
|
|
||||||
|
|||||||
199
silo.svg
Normal file
199
silo.svg
Normal file
@@ -0,0 +1,199 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
width="256"
|
||||||
|
height="256"
|
||||||
|
viewBox="0 0 67.733333 67.733333"
|
||||||
|
version="1.1"
|
||||||
|
id="svg1"
|
||||||
|
inkscape:version="1.4.3 (fcd0343856, 2026-01-01)"
|
||||||
|
sodipodi:docname="silo.svg"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview1"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#000000"
|
||||||
|
borderopacity="0.25"
|
||||||
|
inkscape:showpageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:deskcolor="#d1d1d1"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
inkscape:zoom="2.2803882"
|
||||||
|
inkscape:cx="64.243447"
|
||||||
|
inkscape:cy="110.72676"
|
||||||
|
inkscape:window-width="1854"
|
||||||
|
inkscape:window-height="1011"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="layer1" />
|
||||||
|
<defs
|
||||||
|
id="defs1">
|
||||||
|
<inkscape:perspective
|
||||||
|
sodipodi:type="inkscape:persp3d"
|
||||||
|
inkscape:vp_x="14.357431 : 46.829376 : 1"
|
||||||
|
inkscape:vp_y="0 : 1000 : 0"
|
||||||
|
inkscape:vp_z="67.733333 : 33.866667 : 1"
|
||||||
|
inkscape:persp3d-origin="33.866667 : 22.577778 : 1"
|
||||||
|
id="perspective2" />
|
||||||
|
<inkscape:path-effect
|
||||||
|
effect="bspline"
|
||||||
|
id="path-effect29"
|
||||||
|
is_visible="true"
|
||||||
|
lpeversion="1.3"
|
||||||
|
weight="33.333333"
|
||||||
|
steps="2"
|
||||||
|
helper_size="0"
|
||||||
|
apply_no_weight="true"
|
||||||
|
apply_with_weight="true"
|
||||||
|
only_selected="false"
|
||||||
|
uniform="false" />
|
||||||
|
<inkscape:path-effect
|
||||||
|
effect="fillet_chamfer"
|
||||||
|
id="path-effect28"
|
||||||
|
is_visible="true"
|
||||||
|
lpeversion="1"
|
||||||
|
nodesatellites_param="F,0,0,1,0,3.9200752,0,1 @ F,0,0,1,0,4.1239928,0,1 @ F,0,0,1,0,4.8617729,0,1 @ F,0,0,1,0,4.8211703,0,1 @ F,0,0,1,0,4.5493151,0,1 @ F,0,0,1,0,4.4938558,0,1"
|
||||||
|
radius="0"
|
||||||
|
unit="px"
|
||||||
|
method="auto"
|
||||||
|
mode="F"
|
||||||
|
chamfer_steps="1"
|
||||||
|
flexible="false"
|
||||||
|
use_knot_distance="true"
|
||||||
|
apply_no_radius="true"
|
||||||
|
apply_with_radius="true"
|
||||||
|
only_selected="false"
|
||||||
|
hide_knots="false" />
|
||||||
|
<inkscape:path-effect
|
||||||
|
effect="fillet_chamfer"
|
||||||
|
id="path-effect27"
|
||||||
|
is_visible="true"
|
||||||
|
lpeversion="1"
|
||||||
|
nodesatellites_param="F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
|
||||||
|
radius="0"
|
||||||
|
unit="px"
|
||||||
|
method="auto"
|
||||||
|
mode="F"
|
||||||
|
chamfer_steps="1"
|
||||||
|
flexible="false"
|
||||||
|
use_knot_distance="true"
|
||||||
|
apply_no_radius="true"
|
||||||
|
apply_with_radius="true"
|
||||||
|
only_selected="false"
|
||||||
|
hide_knots="false" />
|
||||||
|
<inkscape:path-effect
|
||||||
|
effect="bspline"
|
||||||
|
id="path-effect18"
|
||||||
|
is_visible="true"
|
||||||
|
lpeversion="1.3"
|
||||||
|
weight="33.333333"
|
||||||
|
steps="2"
|
||||||
|
helper_size="0"
|
||||||
|
apply_no_weight="true"
|
||||||
|
apply_with_weight="true"
|
||||||
|
only_selected="false"
|
||||||
|
uniform="false" />
|
||||||
|
<inkscape:path-effect
|
||||||
|
effect="bspline"
|
||||||
|
id="path-effect17"
|
||||||
|
is_visible="true"
|
||||||
|
lpeversion="1.3"
|
||||||
|
weight="33.333333"
|
||||||
|
steps="2"
|
||||||
|
helper_size="0"
|
||||||
|
apply_no_weight="true"
|
||||||
|
apply_with_weight="true"
|
||||||
|
only_selected="false"
|
||||||
|
uniform="false" />
|
||||||
|
<rect
|
||||||
|
x="420.0712"
|
||||||
|
y="303.34592"
|
||||||
|
width="1.3979075"
|
||||||
|
height="15.376982"
|
||||||
|
id="rect10" />
|
||||||
|
<inkscape:path-effect
|
||||||
|
effect="bspline"
|
||||||
|
id="path-effect17-1"
|
||||||
|
is_visible="true"
|
||||||
|
lpeversion="1.3"
|
||||||
|
weight="33.333333"
|
||||||
|
steps="2"
|
||||||
|
helper_size="0"
|
||||||
|
apply_no_weight="true"
|
||||||
|
apply_with_weight="true"
|
||||||
|
only_selected="false"
|
||||||
|
uniform="false" />
|
||||||
|
</defs>
|
||||||
|
<g
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer2"
|
||||||
|
inkscape:label="Layer 2" />
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1">
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
transform="scale(0.26458333)"
|
||||||
|
id="text10"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;writing-mode:lr-tb;direction:ltr;white-space:pre;shape-inside:url(#rect10);display:inline;fill:#000000" />
|
||||||
|
<path
|
||||||
|
d="M 20.428727,7.2855111 A 11.978197,11.814115 0 0 0 8.4501302,19.09926 H 32.406807 A 11.978197,11.814115 0 0 0 20.428727,7.2855111 Z"
|
||||||
|
style="stroke-width:0.266414;fill:#cb5633;fill-opacity:1;stroke:#000000;stroke-opacity:1"
|
||||||
|
id="path13" />
|
||||||
|
<path
|
||||||
|
d="M 32.451249,56.100619 H 8.4501302 a 12.000372,4.1021233 0 0 0 12.0008178,4.102076 12.000372,4.1021233 0 0 0 12.000301,-4.102076 z"
|
||||||
|
style="stroke-width:0.299701;fill:#cb5633;fill-opacity:1;stroke:#000000;stroke-opacity:1"
|
||||||
|
id="path9" />
|
||||||
|
<path
|
||||||
|
d="M 32.406807,19.09926 H 8.4501302 A 11.978197,11.814115 0 0 0 20.428727,30.913526 11.978197,11.814115 0 0 0 32.406807,19.09926 Z"
|
||||||
|
style="stroke-width:0.33633;fill:#cb5633;fill-opacity:1;stroke:#000000;stroke-opacity:1"
|
||||||
|
id="path12" />
|
||||||
|
<path
|
||||||
|
d="M 32.406807,19.09926 A 11.978197,11.814115 0 0 1 20.428727,30.913526 11.978197,11.814115 0 0 1 8.4501302,19.09926 V 56.100619 A 12.000372,4.1021233 0 0 1 20.450948,51.998544 12.000372,4.1021233 0 0 1 32.451249,56.100619 V 19.09926 Z"
|
||||||
|
style="stroke-width:0.33633;fill:#cb5633;fill-opacity:1;stroke:#000000;stroke-opacity:1"
|
||||||
|
id="path11" />
|
||||||
|
<path
|
||||||
|
d="M 32.451249,56.100619 A 12.000372,4.1021233 0 0 0 20.450948,51.998544 12.000372,4.1021233 0 0 0 8.4501302,56.100619 Z"
|
||||||
|
style="stroke-width:0.33633;fill:#cb5633;fill-opacity:1;stroke:#000000;stroke-opacity:1"
|
||||||
|
id="path10" />
|
||||||
|
<path
|
||||||
|
sodipodi:type="star"
|
||||||
|
style="fill:#000000;stroke:#f1d789;stroke-width:0.665;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="path7"
|
||||||
|
inkscape:flatsided="true"
|
||||||
|
sodipodi:sides="6"
|
||||||
|
sodipodi:cx="41.67757"
|
||||||
|
sodipodi:cy="55.952961"
|
||||||
|
sodipodi:r1="20.923403"
|
||||||
|
sodipodi:r2="18.120197"
|
||||||
|
sodipodi:arg1="-1.5707963"
|
||||||
|
sodipodi:arg2="-1.0471976"
|
||||||
|
inkscape:rounded="0"
|
||||||
|
inkscape:randomized="0"
|
||||||
|
d="m 41.677571,35.029558 18.120198,10.461702 -1e-6,20.923403 -18.120198,10.461701 -18.120198,-10.461702 0,-20.923403 z"
|
||||||
|
transform="matrix(0.74549523,0,0,0.74549523,16.552636,5.9857271)" />
|
||||||
|
<path
|
||||||
|
sodipodi:type="star"
|
||||||
|
style="fill:#000000;stroke:#f1d789;stroke-width:0.665;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="path7-3"
|
||||||
|
inkscape:flatsided="true"
|
||||||
|
sodipodi:sides="6"
|
||||||
|
sodipodi:cx="41.67757"
|
||||||
|
sodipodi:cy="55.952961"
|
||||||
|
sodipodi:r1="20.923403"
|
||||||
|
sodipodi:r2="18.120197"
|
||||||
|
sodipodi:arg1="-1.5707963"
|
||||||
|
sodipodi:arg2="-1.0471976"
|
||||||
|
inkscape:rounded="0"
|
||||||
|
inkscape:randomized="0"
|
||||||
|
d="m 41.677571,35.029558 18.120198,10.461702 -1e-6,20.923403 -18.120198,10.461701 -18.120198,-10.461702 0,-20.923403 z"
|
||||||
|
transform="matrix(0.74549523,0,0,0.74549523,16.552636,-9.6125699)" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 7.1 KiB |
Reference in New Issue
Block a user