projection.ts
Language TypeScript4.0 KB125 lines
/*** What the sync keeps from a Plinth order.** Not the Northgate rules. The agency's Plinth schema notes classify fields for a* client-facing integration where an unverified caller might see the response;* hence their very aggressive `strip` list. This dashboard is internal, behind* auth, read by a small team who already have Plinth logins. Those constraints do* not transfer.** The line used here is the team's existing data-handling rule:** "Client names in an order context are fine. Contact details, addresses, and* payment information are not."** There is a practical reason on top of the policy one. The snapshot database is* a new copy of customer data in a new place. Keeping a name and a company costs* nothing and makes every row readable at a glance. Keeping billing addresses,* emails, and phone numbers turns this dashboard's storage into a secondary PII* store that has to be secured, backed up, and eventually deleted, in exchange* for fields no panel displays.** If a panel ever needs a dropped field, add it here deliberately rather than* widening the projection "just in case."*//** Order-level fields the snapshot keeps. */export const ORDER_FIELDS = ['order_ref','status_code','status_label','closed_on', // NOTE: order PLACED datetime, despite the name.'grand_total','subtotal','shipping_total','discount_total','ship_weight','account_ref','account_kind','shop','dept_ref','customer_group', // Retail / Palladium Partner / ...: segment, not PII'sales_rep', // null on every order sampled so far'press_name', // the VENDOR, not a designer'production_owner', // order-level assignment'account_owner', // note the spelling; also per product line (see PRODUCT_FIELDS)'proof_approver','tracking_no','carier_name', // sic'purchase_order',] as const/** Identifying-but-useful. Kept per the data-handling rule above: names in an order context. */export const ORDER_IDENTITY_FIELDS = ['first_name','last_name','company_name','ship_company',] as const/** Product-line fields. Where the real design/production status lives. */export const PRODUCT_FIELDS = ['line_ref','item_ref','line_status','line_status_code', // preferred over the name'production_owner', // the designer'account_owner', // the CS rep (note the spelling)'item_name','qty','unit_price','item_size','kit_flag','storage_days',] as const/*** Explicitly dropped. Listed rather than merely omitted so the decision is* visible and reversible, and so nobody re-adds them by accident.*/export const DROPPED_FIELDS = {contact: ['email', 'phone'],addresses: ['ship_name','ship_street','ship_district','ship_city','ship_postcode','ship_region','ship_region_code','ship_country','bill_name','bill_company','bill_street','bill_district','bill_city','bill_postcode','bill_region','bill_region_code','bill_country',],payment: ['tax_total'],/*** Artwork URL sets. Dropped for size, not sensitivity: a five-panel booth* carries ~36 CloudFront URLs across customer-supplied, print-ready, and* thumbnail variants. Nothing on the dashboard renders them, and persisting* them would multiply snapshot size for no gain. Fetch on demand from a* detail view if one is ever built.*/artwork: ['printfile_info'],} as constconst KEEP = new Set<string>([...ORDER_FIELDS, ...ORDER_IDENTITY_FIELDS])const KEEP_PRODUCT = new Set<string>(PRODUCT_FIELDS)export function projectOrder(raw: Record<string, unknown>): Record<string, unknown> {const out: Record<string, unknown> = {}for (const k of Object.keys(raw)) if (KEEP.has(k)) out[k] = raw[k]return out}export function projectProduct(raw: Record<string, unknown>): Record<string, unknown> {const out: Record<string, unknown> = {}for (const k of Object.keys(raw)) if (KEEP_PRODUCT.has(k)) out[k] = raw[k]return out}