docs: update stale documentation to reflect current state
Closes #1 — Bring documentation in line with implemented features. GAP_ANALYSIS.md: - Mark auth system and audit log gaps as Implemented - Replace FreeCAD Integration section with Client Integration (silo-mod) - Update Phase 2 sections: auth and audit marked COMPLETE - Update Appendix A file structure and Appendix B endpoints STATUS.md: - Update client integrations to reference silo-mod and silo-calc repos - Update unit tests row to remove pkg/calc/tests reference ROADMAP.md: - Update executive summary with links to silo-mod and silo-calc - Update unit tests row, CAD gap section references SPECIFICATION.md: - Update architecture overview to reference silo-mod and silo-calc - Update Section 5 Client Integration with both repos REPOSITORY_STATUS.md: - Remove Python/FreeCAD row from language stats, update totals
This commit is contained in:
@@ -1,14 +1,14 @@
|
||||
# Silo: Item Database and Part Management System for FreeCAD
|
||||
# Silo: Item Database and Part Management System
|
||||
|
||||
**Version:** 0.1 Draft
|
||||
**Date:** January 2026
|
||||
**Version:** 0.2
|
||||
**Date:** February 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.
|
||||
Silo is an item database with configurable part number generation, designed for R&D-oriented workflows. It provides revision tracking, BOM management, file versioning, and physical inventory location management through a REST API and web UI. CAD integration (FreeCAD workbench, LibreOffice Calc extension) is maintained in separate repositories ([silo-mod](https://git.kindred-systems.com/kindred/silo-mod), [silo-calc](https://git.kindred-systems.com/kindred/silo-calc)).
|
||||
|
||||
### 1.1 Core Philosophy
|
||||
|
||||
@@ -29,53 +29,45 @@ Silo treats **part numbering schemas as configuration, not code**. Multiple numb
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ FreeCAD 1.0+ │
|
||||
│ ┌─────────────────────────────────────────────────────┐ │
|
||||
│ │ Silo Workbench (Python) │ │
|
||||
│ │ - silo checkout / commit / status / log │ │
|
||||
│ │ - Part number generation │ │
|
||||
│ │ - Property sync with FreeCAD objects │ │
|
||||
│ └─────────────────────────────────────────────────────┘ │
|
||||
│ CAD Clients (silo-mod, silo-calc) │
|
||||
│ FreeCAD Workbench · LibreOffice Calc Extension │
|
||||
│ (maintained in separate repositories) │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
│ REST API
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ Silo Core (CLI/Library) │
|
||||
│ Silo Server (silod) │
|
||||
│ - REST API (74 endpoints) │
|
||||
│ - Authentication (local, LDAP, OIDC) │
|
||||
│ - Schema parsing and validation │
|
||||
│ - Part number generation engine │
|
||||
│ - Revision management │
|
||||
│ - Relationship graph │
|
||||
│ - Relationship graph / BOM │
|
||||
│ - Web UI (htmx) │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
┌───────────────┴───────────────┐
|
||||
▼ ▼
|
||||
┌─────────────────────────┐ ┌─────────────────────────────┐
|
||||
│ PostgreSQL │ │ MinIO │
|
||||
│ (psql.kindred.internal)│ │ - .FCStd file storage │
|
||||
│ (psql.kindred.internal)│ │ - File storage │
|
||||
│ - Item metadata │ │ - Versioned objects │
|
||||
│ - Relationships │ │ - Thumbnails │
|
||||
│ - Revision history │ │ │
|
||||
│ - Location hierarchy │ │ │
|
||||
│ - Auth / Sessions │ │ │
|
||||
│ - Audit log │ │ │
|
||||
└─────────────────────────┘ └─────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ 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 |
|
||||
| Database | PostgreSQL 16 | Existing instance at psql.kindred.internal |
|
||||
| File Storage | MinIO | S3-compatible, versioning enabled |
|
||||
| FreeCAD Integration | Python workbench | Macro-style commands |
|
||||
| CLI & API Server | Go (1.23) | chi/v5 router, pgx/v5 driver, zerolog |
|
||||
| CLI & API Server | Go (1.24) | chi/v5 router, pgx/v5 driver, zerolog |
|
||||
| Authentication | Multi-backend | Local (bcrypt), LDAP/FreeIPA, OIDC/Keycloak |
|
||||
| Sessions | PostgreSQL pgxstore | alexedwards/scs, 24h lifetime |
|
||||
| Web UI | Go html/template + htmx | Lightweight, minimal JS |
|
||||
|
||||
---
|
||||
@@ -347,52 +339,24 @@ assembly_config:
|
||||
|
||||
---
|
||||
|
||||
## 5. FreeCAD Integration
|
||||
## 5. Client Integration
|
||||
|
||||
### 5.1 Workbench Commands
|
||||
CAD workbench and spreadsheet extension implementations are maintained in separate repositories ([silo-mod](https://git.kindred-systems.com/kindred/silo-mod), [silo-calc](https://git.kindred-systems.com/kindred/silo-calc)). The Silo server provides the REST API endpoints consumed by those clients.
|
||||
|
||||
The Silo workbench provides toolbar commands in FreeCAD:
|
||||
### 5.1 File Storage Strategy
|
||||
|
||||
| Command | Description | Status |
|
||||
|---------|-------------|--------|
|
||||
| `Silo_Save` | Auto-save document and upload to MinIO | Implemented |
|
||||
| `Silo_Commit` | Save with revision comment | Implemented |
|
||||
| `Silo_Pull` | Download item by part number / create new | Implemented |
|
||||
| `Silo_Push` | Batch upload modified files | Implemented |
|
||||
| `Silo_Info` | View revision history for current item | Implemented |
|
||||
| `Silo_Register` | Generate part number for current document | Implemented |
|
||||
| `Silo_Open` | Open item from Silo by part number | Implemented |
|
||||
| `Silo_Browse` | Browse items in a list dialog | Implemented |
|
||||
Files are stored as whole objects in MinIO with versioning enabled. Storage path convention: `items/{partNumber}/rev{N}.ext`. SHA-256 checksums are captured on upload for integrity verification.
|
||||
|
||||
### 5.2 Property Synchronization
|
||||
Future option: exploded storage (unpack ZIP-based CAD archives for better diffing).
|
||||
|
||||
Silo properties map to FreeCAD custom properties:
|
||||
### 5.2 Checkout Locking (Future)
|
||||
|
||||
```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:
|
||||
Future multi-user support will need a server-side 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).
|
||||
Recommendation: Pessimistic locking for CAD files (merge is impractical).
|
||||
|
||||
---
|
||||
|
||||
@@ -533,34 +497,40 @@ All operations logged for audit trail (future consideration).
|
||||
|
||||
---
|
||||
|
||||
## 10. Authentication (Future)
|
||||
## 10. Authentication
|
||||
|
||||
### 10.1 Current State (MVP)
|
||||
Silo supports three authentication backends that can be enabled independently or combined. When authentication is disabled (`auth.enabled: false`), all routes are open and a synthetic dev user with the `admin` role is injected into every request.
|
||||
|
||||
Single-user, no authentication required.
|
||||
### 10.1 Backends
|
||||
|
||||
### 10.2 Future: LDAPS Integration
|
||||
| Backend | Use Case | Config Key |
|
||||
|---------|----------|------------|
|
||||
| **Local** | Username/password stored in database (bcrypt cost 12) | `auth.local` |
|
||||
| **LDAP** | FreeIPA / Active Directory via LDAP bind | `auth.ldap` |
|
||||
| **OIDC** | Keycloak or any OpenID Connect provider (redirect flow) | `auth.oidc` |
|
||||
|
||||
Plan for FreeIPA integration:
|
||||
### 10.2 Role Model
|
||||
|
||||
```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"]
|
||||
```
|
||||
Three roles with a strict hierarchy: `admin > editor > viewer`
|
||||
|
||||
| Permission | viewer | editor | admin |
|
||||
|-----------|--------|--------|-------|
|
||||
| Read items, projects, schemas, BOMs | Yes | Yes | Yes |
|
||||
| Create/update items and revisions | No | Yes | Yes |
|
||||
| Upload files, manage BOMs | No | Yes | Yes |
|
||||
| Import CSV/ODS | No | Yes | Yes |
|
||||
| Manage own API tokens | Yes | Yes | Yes |
|
||||
| User management (future) | No | No | Yes |
|
||||
|
||||
### 10.3 API Tokens
|
||||
|
||||
Raw token format: `silo_` + 64 hex characters (32 random bytes from `crypto/rand`). Only the SHA-256 hash is stored in the database. Tokens inherit the owning user's role.
|
||||
|
||||
### 10.4 Sessions
|
||||
|
||||
PostgreSQL-backed sessions via `alexedwards/scs` pgxstore. Cookie: `silo_session`, HttpOnly, SameSite=Lax, 24h lifetime. `Secure` flag is set when `auth.enabled` is true.
|
||||
|
||||
See [AUTH.md](AUTH.md) for full architecture details and [AUTH_USER_GUIDE.md](AUTH_USER_GUIDE.md) for setup instructions.
|
||||
|
||||
---
|
||||
|
||||
@@ -569,60 +539,111 @@ auth:
|
||||
### 11.1 REST Endpoints (Implemented)
|
||||
|
||||
```
|
||||
# Health
|
||||
# Health (no auth)
|
||||
GET /health # Basic health check
|
||||
GET /ready # Readiness (DB + MinIO)
|
||||
|
||||
# Web UI
|
||||
GET / # Items page
|
||||
GET /schemas # Schemas page
|
||||
# Auth (no auth required)
|
||||
GET /login # Login page
|
||||
POST /login # Login form handler
|
||||
POST /logout # Logout
|
||||
GET /auth/oidc # OIDC login redirect
|
||||
GET /auth/callback # OIDC callback
|
||||
|
||||
# Schemas
|
||||
# Web UI (auth + CSRF)
|
||||
GET / # Items page
|
||||
GET /projects # Projects page
|
||||
GET /schemas # Schemas page
|
||||
GET /audit # Audit/completeness page
|
||||
GET /settings # User settings / token management
|
||||
POST /settings/tokens # Create API token (web)
|
||||
POST /settings/tokens/{id}/revoke # Revoke API token (web)
|
||||
|
||||
# Auth API
|
||||
GET /api/auth/me # Current authenticated user
|
||||
GET /api/auth/tokens # List user's API tokens
|
||||
POST /api/auth/tokens # Create API token
|
||||
DELETE /api/auth/tokens/{id} # Revoke API token
|
||||
|
||||
# Schemas (read: viewer, write: editor)
|
||||
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
|
||||
POST /api/schemas/{name}/segments/{segment}/values # Add enum value [editor]
|
||||
PUT /api/schemas/{name}/segments/{segment}/values/{code} # Update enum value [editor]
|
||||
DELETE /api/schemas/{name}/segments/{segment}/values/{code} # Delete enum value [editor]
|
||||
|
||||
# Projects
|
||||
# Projects (read: viewer, write: editor)
|
||||
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
|
||||
GET /api/projects/{code}/sheet.ods # Export project sheet as ODS
|
||||
POST /api/projects # Create project [editor]
|
||||
PUT /api/projects/{code} # Update project [editor]
|
||||
DELETE /api/projects/{code} # Delete project [editor]
|
||||
|
||||
# Items
|
||||
GET /api/items # List/search items
|
||||
POST /api/items # Create item
|
||||
# Items (read: viewer, write: editor)
|
||||
GET /api/items # List/filter items
|
||||
GET /api/items/search # Fuzzy search
|
||||
GET /api/items/export.csv # Export items to CSV
|
||||
POST /api/items/import # Import items from CSV
|
||||
GET /api/items/template.csv # Get CSV import template
|
||||
GET /api/items/template.csv # CSV import template
|
||||
GET /api/items/export.ods # Export items to ODS
|
||||
GET /api/items/template.ods # ODS import template
|
||||
POST /api/items # Create item [editor]
|
||||
POST /api/items/import # Import items from CSV [editor]
|
||||
POST /api/items/import.ods # Import items from ODS [editor]
|
||||
|
||||
# Item Detail
|
||||
GET /api/items/{partNumber} # Get item details
|
||||
PUT /api/items/{partNumber} # Update item
|
||||
DELETE /api/items/{partNumber} # Archive item
|
||||
PUT /api/items/{partNumber} # Update item [editor]
|
||||
DELETE /api/items/{partNumber} # Archive item [editor]
|
||||
|
||||
# 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
|
||||
POST /api/items/{partNumber}/projects # Add project tags [editor]
|
||||
DELETE /api/items/{partNumber}/projects/{code} # Remove project tag [editor]
|
||||
|
||||
# Revisions
|
||||
GET /api/items/{partNumber}/revisions # List revisions
|
||||
POST /api/items/{partNumber}/revisions # Create revision
|
||||
GET /api/items/{partNumber}/revisions/compare # Compare two revisions
|
||||
GET /api/items/{partNumber}/revisions/{revision} # Get specific revision
|
||||
PATCH /api/items/{partNumber}/revisions/{revision} # Update status/labels
|
||||
POST /api/items/{partNumber}/revisions/{revision}/rollback # Rollback to revision
|
||||
POST /api/items/{partNumber}/revisions # Create revision [editor]
|
||||
PATCH /api/items/{partNumber}/revisions/{revision} # Update status/labels [editor]
|
||||
POST /api/items/{partNumber}/revisions/{revision}/rollback # Rollback to revision [editor]
|
||||
|
||||
# Files
|
||||
POST /api/items/{partNumber}/file # Upload file
|
||||
GET /api/items/{partNumber}/file # Download latest file
|
||||
GET /api/items/{partNumber}/file/{revision} # Download file at revision
|
||||
POST /api/items/{partNumber}/file # Upload file [editor]
|
||||
|
||||
# Part Number Generation
|
||||
POST /api/generate-part-number # Generate without creating item
|
||||
# BOM
|
||||
GET /api/items/{partNumber}/bom # List direct children
|
||||
GET /api/items/{partNumber}/bom/expanded # Multi-level BOM (recursive)
|
||||
GET /api/items/{partNumber}/bom/where-used # Where-used (parent lookup)
|
||||
GET /api/items/{partNumber}/bom/export.csv # Export BOM as CSV
|
||||
GET /api/items/{partNumber}/bom/export.ods # Export BOM as ODS
|
||||
POST /api/items/{partNumber}/bom # Add BOM entry [editor]
|
||||
POST /api/items/{partNumber}/bom/import # Import BOM from CSV [editor]
|
||||
PUT /api/items/{partNumber}/bom/{childPartNumber} # Update BOM entry [editor]
|
||||
DELETE /api/items/{partNumber}/bom/{childPartNumber} # Remove BOM entry [editor]
|
||||
|
||||
# Audit (viewer)
|
||||
GET /api/audit/completeness # Item completeness scores
|
||||
GET /api/audit/completeness/{partNumber} # Item detail breakdown
|
||||
|
||||
# Integrations — Odoo (read: viewer, write: editor)
|
||||
GET /api/integrations/odoo/config # Get Odoo configuration
|
||||
GET /api/integrations/odoo/sync-log # Get sync history
|
||||
PUT /api/integrations/odoo/config # Update Odoo config [editor]
|
||||
POST /api/integrations/odoo/test-connection # Test connection [editor] (stub)
|
||||
POST /api/integrations/odoo/sync/push/{partNumber} # Push to Odoo [editor] (stub)
|
||||
POST /api/integrations/odoo/sync/pull/{odooId} # Pull from Odoo [editor] (stub)
|
||||
|
||||
# Sheets (editor)
|
||||
POST /api/sheets/diff # Diff ODS sheet against DB [editor]
|
||||
|
||||
# Part Number Generation (editor)
|
||||
POST /api/generate-part-number # Generate without creating item [editor]
|
||||
```
|
||||
|
||||
### 11.2 Not Yet Implemented
|
||||
@@ -630,14 +651,16 @@ POST /api/generate-part-number # Generate without c
|
||||
The following endpoints from the original design are not yet implemented:
|
||||
|
||||
```
|
||||
# Locations (tables exist, no API)
|
||||
# Locations (tables exist, no API handlers)
|
||||
GET /api/locations
|
||||
POST /api/locations
|
||||
GET /api/locations/{path}
|
||||
DELETE /api/locations/{path}
|
||||
|
||||
# Inventory (tables exist, no API)
|
||||
# Inventory (tables exist, no API handlers)
|
||||
GET /api/inventory/{partNumber}
|
||||
POST /api/inventory/{partNumber}/adjust
|
||||
POST /api/inventory/{partNumber}/move
|
||||
```
|
||||
|
||||
---
|
||||
@@ -646,20 +669,29 @@ POST /api/inventory/{partNumber}/adjust
|
||||
|
||||
### 12.1 Implemented
|
||||
|
||||
- [x] PostgreSQL database schema (7 migrations)
|
||||
- [x] PostgreSQL database schema (10 migrations)
|
||||
- [x] YAML schema parser for part numbering
|
||||
- [x] Part number generation engine
|
||||
- [x] CLI tool (`cmd/silo`)
|
||||
- [x] API server (`cmd/silod`) with 35+ endpoints
|
||||
- [x] FreeCAD workbench (save, commit, pull, push, info, register, open, browse)
|
||||
- [x] API server (`cmd/silod`) with 74 endpoints
|
||||
- [x] MinIO integration for file storage with versioning
|
||||
- [x] BOM relationships (component, alternate, reference)
|
||||
- [x] Multi-level BOM (recursive expansion with configurable depth)
|
||||
- [x] Where-used queries (reverse parent lookup)
|
||||
- [x] BOM CSV and ODS export/import
|
||||
- [x] Reference designator tracking
|
||||
- [x] Revision history (append-only) with rollback and comparison
|
||||
- [x] Revision status and labels
|
||||
- [x] Project management with many-to-many item tagging
|
||||
- [x] CSV import/export with dry-run validation
|
||||
- [x] Web UI for items and schemas (htmx)
|
||||
- [x] ODS spreadsheet import/export (items, BOMs, project sheets)
|
||||
- [x] Web UI for items, projects, schemas, audit (htmx)
|
||||
- [x] Authentication (local, LDAP, OIDC) with role-based access control
|
||||
- [x] API token management (SHA-256 hashed)
|
||||
- [x] Session management (PostgreSQL-backed)
|
||||
- [x] Audit logging and completeness scoring
|
||||
- [x] CSRF protection (nosurf)
|
||||
- [x] Fuzzy search
|
||||
- [x] Property schema versioning framework
|
||||
- [x] Docker Compose deployment (dev and prod)
|
||||
- [x] systemd service and deployment scripts
|
||||
@@ -670,17 +702,15 @@ POST /api/inventory/{partNumber}/adjust
|
||||
- [ ] Inventory tracking (database tables exist, no API endpoints)
|
||||
- [ ] Date segment type (schema parser placeholder only)
|
||||
- [ ] Part number format validation on creation
|
||||
- [ ] Odoo ERP integration (config and sync-log functional; push/pull are stubs)
|
||||
|
||||
### 12.3 Not Started
|
||||
|
||||
- [ ] Unit tests
|
||||
- [ ] Unit tests (Go server — minimal coverage exists)
|
||||
- [ ] Schema migration tooling
|
||||
- [ ] Multi-user authentication (FreeIPA/LDAP planned)
|
||||
- [ ] Checkout locking
|
||||
- [ ] Approval workflows
|
||||
- [ ] External system integrations (ERP, purchasing)
|
||||
- [ ] Exploded file storage with diffing
|
||||
- [ ] Audit logging
|
||||
- [ ] Notifications
|
||||
- [ ] Reporting/analytics
|
||||
|
||||
@@ -688,15 +718,11 @@ POST /api/inventory/{partNumber}/adjust
|
||||
|
||||
## 13. Open Questions
|
||||
|
||||
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.
|
||||
1. **Thumbnail generation**: Generate thumbnails from CAD files on commit? Useful for web UI browsing.
|
||||
|
||||
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. **Search indexing**: PostgreSQL full-text search sufficient, or add dedicated search (Meilisearch, etc.)?
|
||||
|
||||
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.
|
||||
3. **Checkout locking**: Pessimistic vs optimistic locking strategy for multi-user CAD file editing.
|
||||
|
||||
---
|
||||
|
||||
@@ -706,7 +732,6 @@ POST /api/inventory/{partNumber}/adjust
|
||||
|
||||
- **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
|
||||
|
||||
Reference in New Issue
Block a user