feat(plating): recipe-level cert suppression Booleans

Adds five requires_* Booleans on fusion.plating.process.node
(requires_coc, requires_thickness_report, requires_nadcap_cert,
requires_mill_test, requires_customer_specific), default True.

Recipe is SUPPRESS-ONLY: when False, the recipe never produces that
cert type even if the customer/part requested it. Default True =
existing recipes keep producing the same cert set they produce today.

Surfaced on recipe-level form (node_type == 'recipe'); resolver reads
from job.recipe_id which is always a top-level recipe node.

Post-migrate backfills NULL -> TRUE on existing nodes.

Sub: docs/superpowers/specs/2026-05-27-recipe-cert-toggles-design.md
Task: T2.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
gsinghpal
2026-05-27 01:57:32 -04:00
parent 89267a9f41
commit a5063cc816
3 changed files with 92 additions and 1 deletions

View File

@@ -502,6 +502,56 @@ class FpProcessNode(models.Model):
string='Requires Transition Form',
help='Sub 12b — opens the transition form before Mark Done.',
)
# Certificate Output — recipe-level cert suppression (2026-05-27 sub
# docs/superpowers/specs/2026-05-27-recipe-cert-toggles-design.md).
# Default True for all five so existing recipes keep producing the
# same cert set they produce today. A recipe author flips OFF only
# the types the recipe physically never produces (passivation = no
# thickness; commodity ENP = no nadcap).
#
# Precedence (Q1 locked decision): recipe SUPPRESSES ONLY. Customer
# / part flags decide what is requested; recipe can remove from that
# set but never add. See fp.job._resolve_required_cert_types.
#
# Surfaced on the recipe form only when node_type == 'recipe'; the
# fields exist on every node row but the UX hides them deeper in
# the tree to avoid confusing authors. Resolver reads from
# job.recipe_id which is always a top-level recipe node.
requires_coc = fields.Boolean(
string='Requires CoC',
default=True,
help='When False, this recipe never produces a Certificate of '
'Conformance even if the customer/part requested one.',
)
requires_thickness_report = fields.Boolean(
string='Requires Thickness Report',
default=True,
help='When False, this recipe never produces a thickness report. '
'Use for passivation, chemical conversion, anodize seal-only, '
'etc. — processes that physically have no plating thickness '
'to measure.',
)
requires_nadcap_cert = fields.Boolean(
string='Requires Nadcap Certificate',
default=True,
help='When False, this recipe never auto-spawns a Nadcap cert. '
'Use for commodity recipes that the shop does not run under '
'Nadcap accreditation.',
)
requires_mill_test = fields.Boolean(
string='Requires Mill Test Report',
default=True,
help='When False, this recipe never auto-spawns a Mill Test Report '
'cert.',
)
requires_customer_specific = fields.Boolean(
string='Requires Customer-Specific Cert',
default=True,
help='When False, this recipe never auto-spawns a Customer-Specific '
'cert.',
)
# Sub 14b — User-extensible Step Kinds (was Selection of 24).
# 2026-05-20: required + ondelete='restrict' — kind drives gates,
# workflow milestones, and operator routing. Optional was a foot-gun