PRODUCT.1287 — Field & Program Map
Canonical map of the
PRODUCT.1287UniData table: its dictionary (field layout), how densely those fields are actually populated, and the AFTEC BASIC programs inS:\LinuxShare\pro3progthat read or write it. Built 2026-07-06 from the live DICT (GET /api/dict/dev/tables/PRODUCT.1287), a 200-record data sample, and apro3progsource scan.
What this table is
PRODUCT.1287 is the manufacturing / engineering extension record for a part. It shares its key
(CO!PARTNO, e.g. 1!054761) with the PRODUCT master item — PRODUCT holds the item identity
(description, MRP type, obsolescence flag), and PRODUCT.1287 holds engineering/routing sidecar data
(routing codes, MTBF, safety flag, paint, assembly cross-refs). Think of it as a 1:1 companion to
PRODUCT, not a standalone entity.
Key facts
| File type | F (hashed) |
| Key | CO!PARTNO (company prefix + part number) |
| Dictionary entries | 61 — 36 D-type (31 distinct attribute positions + 5 aliases) + 25 I-type calculated |
| Populated in practice | ~3 attributes carry real data (see fill rates) — the table is defined-rich but data-sparse |
Attribute-8 collision
Attribute 8 is
MTBFin PRODUCT.1287, but attribute 8 is the INC/OBS obsolescence flag in the sibling PRODUCT table. Same position, different file, different meaning. Any code addressing “attr 8” must be explicit about which file it opened.
D-type attributes (physical layout)
Fill % measured over the first 200 records. Aliases (F1≡ENG.STAT, F2≡PROD.DWG, F7≡PHYS,
F8≡MTBF, F12≡PAINT) are collapsed to the semantic name.
| Pos | Field | Conv | Fmt | MV | Fill % | Notes |
|---|---|---|---|---|---|---|
| 1 | ENG.STAT | 3L | ✓ | 3.0 | Engineering status | |
| 2 | PROD.DWG | 20L | 5.0 | Product drawing; also the ASSY→COMP cross-ref slot written by E0052 | ||
| 3 | (F3) FASTENERS | 10R | 0 | |||
| 4 | (F4) CONDUIT | 10R | 0 | |||
| 5 | (F5) CONDUCTORS | 10R | 0 | |||
| 6 | (F6) TERMINATIONS | 10R | 0 | |||
| 7 | PHYS | 6L | 5.0 | Physical part; also the COMP→ASSY cross-ref slot written by E0052 | ||
| 8 | MTBF | 5R | 93.5 | Mean time between failures (hours). Often the literal "NA" | ||
| 9 | F9 (ROUTE CODES) | 1L | ✓ | 91.5 | Routing codes; written by VB_ROUTE.* (attr 9) | |
| 10 | (F10) MANF.PARTNO | 50L | 0 | |||
| 11 | F11 (SAFETY ITEM) | 1L | 39.0 | Safety-item flag | ||
| 12 | PAINT | 2L | 2.0 | |||
| 13 | ASSYCODE | 6L | ✓ | 0 | ||
| 14 | ASSYCOMP | 6L | ✓ | 0 | ||
| 15 | ASSYQTY | 6R | ✓ | 0 | ||
| 16 | ASSYWU | 6L | ✓ | 0 | ||
| 17 | FOOTPRINT | 6L | 0 | |||
| 18 | LAST.REC.DATE | D2/ | 8L | 16.5 | Date (epoch 1967-12-31) | |
| 19 | MRPX | 4L | ✓ | 0 | ||
| 20 | LABEL.RQRD | 1L | 0 | |||
| 21 | PLANORD.NOTE | 15L | 0 | |||
| 22 | LAST.ACT.DATE | D2/ | 8L | 13.5 | Last receipt/issue date | |
| 23 | KEEP.DATE | D2/ | 8L | 0 | ||
| 24 | COUNT.ERR | 10L | ✓ | 0 | ||
| 25 | BODY.BOX | MD2 | 6R | ✓ | 2.5 | Bounding box X/Y/Z (see BB.X/Y/Z) |
| 26 | RSVD.BIN | 6L | 0 | |||
| 27 | WELD.TYPE | 3L | 0.5 | |||
| 28 | TAX.CODE | 8L | 0 | |||
| 29 | PAINT.NOTE | 20L | 0 | |||
| 30 | (F30) PAINT CODES | 1L | ✓ | 0 | ||
| 31 | (F31) PAINT DESC | 10L | ✓ | 0 |
Reality: only MTBF (8), route codes (9), and safety flag (11) are broadly populated; the two date fields are partial (13–17%); the remaining ~25 attributes are effectively empty in the sample.
I-type (calculated) fields — mostly virtual foreign keys
The 25 I-type entries are not stored data — they are DICT expressions evaluated at read time. Many
TRANS() out to other tables, which is the important structural insight: description, MRP type, GT code,
and cost do not live in PRODUCT.1287.
| Field | Conv | Expression | Resolves from |
|---|---|---|---|
DESC | TRANS(PRODUCT,@ID,'F1','X') | PRODUCT (F1) | |
DESC2 | TRANS(PRODUCT,@ID,'F22','X') | PRODUCT (F22) | |
MRPTYPE | TRANS(PRODUCT,@ID,'F10','X') | PRODUCT (F10) | |
GTCODE | TRANS(ITEMMANF,@ID,'F9','X') | ITEMMANF | |
TRANS.ASY | TRANS(ITEMMANF,@ID,'F6','X') | ITEMMANF | |
LMAT | MD4 | TRANS(ITEMCA,CO!PARTNO,'F8','X') | ITEMCA (material cost) |
LCVEND | MD4 | TRANS(ITEMCA,CO!PARTNO,'F10','X') | ITEMCA (vendor cost) |
LCLAB | MD4 | TRANS(ITEMCA,CO!PARTNO,'F12','X') | ITEMCA (labor cost) |
TOTLST | MD4 | LMAT+LCVEND+LCLAB | derived total last cost |
BB.X/BB.Y/BB.Z | MD2 | FIELD(BODY.BOX,@VM,n) | attr 25 split |
CO / PARTNO | FIELD(@ID,"!",n) | key split | |
MW/MECHASSY/ELECASSY/JS.ROUTE | EXTRACT(F9,1,n,0) | route-code positions | |
ERR.BIN/ERR.MVEQTY/ERR.CNTQTY | FIELD(COUNT.ERR,@VM,n) | attr 24 split | |
ASSYCOMP.COUNT/.EXIST, RTE.CNT, C.ENG.STAT | DCOUNT / IF / concat | derived |
Cost lives in ITEMCA, not here. A consumer wanting last cost should read ITEMCA (or the TOTLST
I-type), never a stored PRODUCT.1287 attribute.
Programs in pro3prog that touch PRODUCT.1287
A source scan matched 118 program files (after dropping temp/test/data noise). Collapsed into logical
families and separated by era, the real surface is much smaller. Version families (an OG plus later
customized revisions — .REV1/2/3, A, _DOTNET) are grouped; the _DOTNET suffix marks the variant
forked for the .NET/WCF interop layer.
Writers / mutators (verified by reading the source)
| Program (family) | Live? | Operation on PRODUCT.1287 |
|---|---|---|
VB_WRITEPRODUCT (VBBASE, 2000) | ✅ live | Full-record write — WRITE PART1287REC ON PRODUCT.1287,ID. The canonical write path (used by the .NET write flow) |
E0052 (PBSBASE) + VB_E0052A / VB_E0052A.REV1 (VBBASE) | ✅ live | Interactive part-master assembly↔component maintenance — WRITEVs attr 2 (PROD xref) and 7 (PHYS xref); blanks them on unlink |
VB_ROUTE.REV2 (2021) + .REV1 (2017) + VB_ROUTE.DELETE (2015) | ✅ live (REV2) | Routing — WRITEVU ROUTE.SUGG ON PRODUCT.1287,ROUTEID,9 (maintains route codes at attr 9) |
DELETE.PRODUCT (PBSBASE, 2018) | ✅ live | Guarded delete + cascade — 7 safety checks, then DELETE PRODUCT.1287,KEY and cascades to PRODUCT, PRODUCT.NOTES, ITEMCA, ITEMQTY, ITEMORD, ITEMMANF, ITEMHIST, PRD.PRICE |
VB_DELETE0001 (1997) | legacy | Older delete utility |
VB_UPDATECOST(2025) andPRODUCT.LDS.1287.UPDATE(2002) open/read PRODUCT.1287 but write elsewhere — the former writes cost to ITEMCA/PVXREF, the latter writes the sibling PRODUCT.LDS.1287. They are readers of this table.
Readers — live cohort (2018–2026)
Representative, version-families collapsed:
- BOM engines:
VB_BOMX.REV1(the explosion sub the API calls),VB_BOMLIST.REV1/REV1A/_DOTNET,VB_BOMEXPLORER.3/.3.REV3,VB_BOMNOTROUTED.REV3/REV2/REV1,VB_JOBBOM.REV1,VB_IMPORTBOM.REV1 - Part / product info:
VB_PARTINFO.REV2(API part lookup),VB_PRODUCT.REV1/_DOTNET,VB_PRODUCT_DB+VB_PRODUCT_DB_2(⚠ both declareSUBROUTINE VB_PRODUCT_DB— OG + customized fork),VB_PRODUCTS.REV1,VB_GET.PARTINFO - Inventory / history:
VB_GET.INVENTORY,VB_GET.ITEMHIST,VB_INACT.INVNTY,VB_OPENPOINQ.REV7/REV6 - WIP BOM / spare-parts quoting:
WIPBMF.REV6/REV7/REV8,VB_WIPBMF.REV5,VB_SPQUOTEMAINT2.REV3/REV2/REV1,SP_QUOTELINEINFO,VB_READ.SP.QUOTE.REV1,VB_BMF.REV1 - Reports (PBSBASE, still maintained):
RPT.PARTMASTER,RPT.INVHIST/RPT.INVHIST2,RPT.INVENTORY,RPT.PO,RPT.APHIST,RPT.JOBPARTS,RPT.100HEPARTS,RPT.FIXEDPRICEPARTS,SFPACK,PORECEIPT,UPDATECOSTVENDOR,VB_WO.VERIFY.REV1
Legacy / likely defunct (1995–2002 PBSBASE)
~40 files last touched 1995–2002 — old reporting and batch jobs that reference the table but are almost
certainly out of the live path. Notable clusters: FAC.COST.RPT, FAC.JPC.RPT, FACILITY.RPT,
FACILITY.JPC, JPH.BUILD, JPH.ALLOC.FAC, LDS.RPT, LDS.CNFDNCE2, LDS.INDX.Q, LDS.FLCHA.Q,
the SBOM.* set, the 2013 SP.* spare-parts batch set (SP.MTBF, SP.LIST, SP.ALL.BAT, …),
PROD.BOM.CHK, PROD.ROLLUP, PRODINQ, PRODUCTEM_COPY, E0055/E0055-CONTROL, E0065,
ENGRSCHD, ENGRWO.EM, ECONNECT.RPT, ELECT.CONN.EM, DCROUTE.EM, BLD.JOB.COSTS,
PROMISE.DUMP/PROMISE.UPDATE, MRPSHRTS.AUTO(+.6710), INV.INQ, INACT.INVNTY, NOTROUTED.EM,
CA1740, I.0001, SROUTE.HRS.UPD, CI, BKPLOT.ASSY, JOB.ELEC.EM, JOB.PROD.ROLL, SP.ALL.PROJ.
“Live vs defunct” here is inferred from file mtime + naming + which subs the API demonstrably calls, not from a production VOC/call-graph. Treat the legacy list as candidates for retirement, to be confirmed against actual invocation before any cleanup.
The LDS sidecar — PRODUCT.LDS.1287 and associated
There is a second file keyed on the same CO!PARTNO: PRODUCT.LDS.1287. It is not a hand-edited
peer of PRODUCT.1287 — it is a daily-rebuilt materialized projection derived from it.
How it’s built. PRODUCT.LDS.1287.UPDATE (PBSBASE, authored 2002 by JPT, “run as a daily job”)
selects every non-obsolete product (SELECT PRODUCT WITH GT.CODE='PRODUCT' WITH F8 # 'O') and, per
product, reads PRODUCT.1287 to denormalize product↔physical status plus a classification code:
| Attr | Field | Fill % | Sourced from |
|---|---|---|---|
| 1 | PROD.STAT | 9.0 | PRODUCT.1287 attr 1 (ENG.STAT) of the product |
| 2 | PHYS.NO | 100 | PRODUCT.1287 attr 7 (PHYS) — the product’s physical part |
| 3 | PHYS.STAT | 10.5 | ENG status of that PHYS’s own PRODUCT.1287 record |
| 4 | PROD.CLASS | 97.5 | matched from the product description → PRODUCT.CLASS.1287 |
| 5 | PHOTOS | 0 | (defined, unused in sample) |
Plus 6 I-type helpers (INACT.OBS→PRODUCT INC/OBS, PROD.CLASS.NAME→PRODUCT.CLASS.1287,
PROD.DESC/PROD.DESC2→PRODUCT, CO/PROD.NO key splits). Real payload = PHYS.NO + PROD.CLASS.
Relationship to PRODUCT.1287: downstream, one-way. PRODUCT.1287 is the source of truth (physical part at attr 7, ENG status at attr 1); PRODUCT.LDS.1287 is a flattened daily snapshot for LDS-facing consumers. Editing PRODUCT.LDS.1287 directly is pointless — the daily job overwrites it.
Legacy "LDS" ≠ LDS 4.0
This table’s “LDS” is the 2002 product/physical classification lineage — the conceptual ancestor of, but not the same thing as, the current LDS 4.0 initiative. If LDS 4.0 needs product classification, treat this stale derived table as a candidate to verify-still-running or supersede, not to build on.
Associated tables (the DICT knows 1,489 tables; genuinely LDS-related):
| Table | What it is |
|---|---|
PRODUCT.CLASS.1287 | Class-code → CLASS.NAME lookup that PRODUCT.LDS.1287 resolves PROD.CLASS against |
WORK.LDS.1287 | Thin (F1, F2/LVL) — WIP/level structure, minimal content |
CO.STDS.LDS.1287 | Thin (F1–F4, unnamed) — company-standards LDS, minimal content |
CHILDSUPPORT.1287 | ⚠️ not LDS — a substring false match (chiLDSupport). Actually payroll child-support garnishment data (name, CS.ID, account/routing #, amount). Notable only as PII sitting in the AFTEC schema |
Related
- PRODUCT BOM Structure — product⇄phys⇄components model + fleet BOM audit (single-part vs kit, by class)
- PSI.UniData.API — Dictionary/Schema endpoints used to build this map
- PSI.All Architecture — UniData subroutine catalog
- Data Catalog