feat(db): add source column to relationships table (#44)
Promote BOM source from metadata JSONB to a dedicated VARCHAR(20)
column with CHECK constraint ('manual' or 'assembly').
- Add migration 012_bom_source.sql (column, data migration, cleanup)
- Add Source field to Relationship and BOMEntry structs
- Update all SQL queries (GetBOM, GetWhereUsed, GetExpandedBOM, Create)
- Update API response/request types with source field
- Update CSV/ODS export to read e.Source instead of metadata
- Update CSV import to set source on relationship directly
- Update frontend types and BOMTab to use top-level source field
This commit is contained in:
@@ -29,6 +29,7 @@ type BOMEntryResponse struct {
|
||||
ChildRevision *int `json:"child_revision,omitempty"`
|
||||
EffectiveRevision int `json:"effective_revision"`
|
||||
Depth *int `json:"depth,omitempty"`
|
||||
Source string `json:"source"`
|
||||
Metadata map[string]any `json:"metadata,omitempty"`
|
||||
}
|
||||
|
||||
@@ -51,6 +52,7 @@ type AddBOMEntryRequest struct {
|
||||
Unit *string `json:"unit,omitempty"`
|
||||
ReferenceDesignators []string `json:"reference_designators,omitempty"`
|
||||
ChildRevision *int `json:"child_revision,omitempty"`
|
||||
Source string `json:"source,omitempty"`
|
||||
Metadata map[string]any `json:"metadata,omitempty"`
|
||||
}
|
||||
|
||||
@@ -240,6 +242,7 @@ func (s *Server) HandleAddBOMEntry(w http.ResponseWriter, r *http.Request) {
|
||||
Unit: req.Unit,
|
||||
ReferenceDesignators: req.ReferenceDesignators,
|
||||
ChildRevision: req.ChildRevision,
|
||||
Source: req.Source,
|
||||
Metadata: req.Metadata,
|
||||
}
|
||||
if user := auth.UserFromContext(ctx); user != nil {
|
||||
@@ -273,6 +276,7 @@ func (s *Server) HandleAddBOMEntry(w http.ResponseWriter, r *http.Request) {
|
||||
ReferenceDesignators: req.ReferenceDesignators,
|
||||
ChildRevision: req.ChildRevision,
|
||||
EffectiveRevision: child.CurrentRevision,
|
||||
Source: rel.Source,
|
||||
Metadata: req.Metadata,
|
||||
}
|
||||
if req.ChildRevision != nil {
|
||||
@@ -434,6 +438,7 @@ func bomEntryToResponse(e *db.BOMEntry) BOMEntryResponse {
|
||||
ReferenceDesignators: refDes,
|
||||
ChildRevision: e.ChildRevision,
|
||||
EffectiveRevision: e.EffectiveRevision,
|
||||
Source: e.Source,
|
||||
Metadata: e.Metadata,
|
||||
}
|
||||
}
|
||||
@@ -686,14 +691,14 @@ func (s *Server) HandleExportBOMCSV(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
row := []string{
|
||||
strconv.Itoa(i + 1), // Item
|
||||
strconv.Itoa(e.Depth), // Level
|
||||
getMetaString(e.Metadata, "source"), // Source
|
||||
e.ChildPartNumber, // PN
|
||||
strconv.Itoa(i + 1), // Item
|
||||
strconv.Itoa(e.Depth), // Level
|
||||
e.Source, // Source
|
||||
e.ChildPartNumber, // PN
|
||||
getMetaString(e.Metadata, "seller_description"), // Seller Description
|
||||
unitCostStr, // Unit Cost
|
||||
qtyStr, // QTY
|
||||
extCost, // Ext Cost
|
||||
unitCostStr, // Unit Cost
|
||||
qtyStr, // QTY
|
||||
extCost, // Ext Cost
|
||||
getMetaString(e.Metadata, "sourcing_link"), // Sourcing Link
|
||||
}
|
||||
if err := writer.Write(row); err != nil {
|
||||
@@ -853,12 +858,11 @@ func (s *Server) HandleImportBOMCSV(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
// Build metadata from CSV columns
|
||||
metadata := make(map[string]any)
|
||||
source := ""
|
||||
if idx, ok := headerIdx["source"]; ok && idx < len(record) {
|
||||
if v := strings.TrimSpace(record[idx]); v != "" {
|
||||
metadata["source"] = v
|
||||
}
|
||||
source = strings.TrimSpace(record[idx])
|
||||
}
|
||||
metadata := make(map[string]any)
|
||||
if idx, ok := headerIdx["seller description"]; ok && idx < len(record) {
|
||||
if v := strings.TrimSpace(record[idx]); v != "" {
|
||||
metadata["seller_description"] = v
|
||||
@@ -942,6 +946,7 @@ func (s *Server) HandleImportBOMCSV(w http.ResponseWriter, r *http.Request) {
|
||||
ChildItemID: child.ID,
|
||||
RelType: "component",
|
||||
Quantity: quantity,
|
||||
Source: source,
|
||||
Metadata: metadata,
|
||||
CreatedBy: importUsername,
|
||||
}
|
||||
|
||||
@@ -599,7 +599,7 @@ func (s *Server) HandleExportBOMODS(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
}
|
||||
|
||||
source := getMetaString(e.Metadata, "source")
|
||||
source := e.Source
|
||||
if source == "" && childItem != nil {
|
||||
st := childItem.SourcingType
|
||||
if st == "manufactured" {
|
||||
@@ -754,7 +754,7 @@ func (s *Server) HandleProjectSheetODS(w http.ResponseWriter, r *http.Request) {
|
||||
if e.Quantity != nil {
|
||||
qty = *e.Quantity
|
||||
}
|
||||
source := getMetaString(e.Metadata, "source")
|
||||
source := e.Source
|
||||
if source == "" && childItem != nil {
|
||||
if childItem.SourcingType == "manufactured" {
|
||||
source = "M"
|
||||
|
||||
Reference in New Issue
Block a user