diff --git a/migrations/0013_drug_archive_kind.down.sql b/migrations/0013_drug_archive_kind.down.sql new file mode 100644 index 0000000..cc17d5b --- /dev/null +++ b/migrations/0013_drug_archive_kind.down.sql @@ -0,0 +1,8 @@ +-- Reverse 0013: detach products from the seeded drug categories, drop the drug +-- category subtree, and remove the drug field template. +UPDATE product SET category_id = NULL +WHERE category_id IN (SELECT id FROM category WHERE path <@ 'drug'); + +DELETE FROM category WHERE path <@ 'drug'; + +DELETE FROM kind_field WHERE kind = 'drug'; diff --git a/migrations/0013_drug_archive_kind.up.sql b/migrations/0013_drug_archive_kind.up.sql new file mode 100644 index 0000000..3836e4b --- /dev/null +++ b/migrations/0013_drug_archive_kind.up.sql @@ -0,0 +1,43 @@ +-- Drug (药品) archive kind: a new domain on the generic archive_kind framework +-- (see 0010). No new table — drug spec values live in product.attributes JSONB, +-- driven by the kind_field template below, plus a 'drug' category subtree. + +-- Field template for the drug domain. field_type is constrained to +-- text/number/textarea/select/list by kind_field_type_chk. The `qualified` +-- fields are the identifying / regulatory essentials that count toward the +-- kind-aware completeness score. +INSERT INTO kind_field (kind, field_key, group_label, label_zh, field_type, unit, options, sort_order, qualified) VALUES +('drug','approval_number', '基础信息','批准文号', 'text', NULL, '{}', 10, true), +('drug','generic_name', '基础信息','通用名', 'text', NULL, '{}', 20, true), +('drug','trade_name', '基础信息','商品名', 'text', NULL, '{}', 30, false), +('drug','dosage_form', '基础信息','剂型', 'select', NULL, '{片剂,胶囊剂,颗粒剂,散剂,丸剂,注射剂,口服液,糖浆剂,软膏剂,乳膏剂,凝胶剂,滴剂,喷雾剂,气雾剂,栓剂,贴剂,其他}', 40, true), +('drug','specification', '基础信息','规格', 'text', NULL, '{}', 50, true), +('drug','pack_spec', '基础信息','包装规格', 'text', NULL, '{}', 60, false), +('drug','rx_class', '分类与企业','处方分类', 'select', NULL, '{处方药,甲类OTC,乙类OTC}', 70, true), +('drug','manufacturer', '分类与企业','生产企业', 'text', NULL, '{}', 80, true), +('drug','mah', '分类与企业','上市许可持有人','text', NULL, '{}', 90, false), +('drug','indications', '说明书','适应症/功能主治', 'textarea', NULL, '{}', 100, true), +('drug','dosage_usage', '说明书','用法用量', 'textarea', NULL, '{}', 110, false), +('drug','adverse_reactions', '说明书','不良反应', 'textarea', NULL, '{}', 120, false), +('drug','contraindications', '说明书','禁忌', 'textarea', NULL, '{}', 130, false), +('drug','precautions', '说明书','注意事项', 'textarea', NULL, '{}', 140, false), +('drug','interactions', '说明书','药物相互作用', 'textarea', NULL, '{}', 150, false), +('drug','storage', '贮藏与有效期','贮藏', 'text', NULL, '{}', 160, false), +('drug','shelf_life', '贮藏与有效期','有效期', 'text', NULL, '{}', 170, false), +('drug','spec_source', '贮藏与有效期','说明书来源', 'text', NULL, '{}', 180, false); + +-- Drug category tree. ltree labels are English slugs (no spaces/Chinese); +-- Chinese names live in category.name_zh. +INSERT INTO category (name_zh, name_en, parent_id, path, level, archive_kind) +VALUES ('药品', 'Drug', NULL, 'drug', 0, 'drug'); + +INSERT INTO category (name_zh, name_en, parent_id, path, level, archive_kind) +SELECT v.name_zh, v.name_en, c.id, v.path::ltree, 1, 'drug' +FROM (VALUES + ('化学药品', 'Chemical drug', 'drug.chemical'), + ('中成药', 'Chinese patent medicine', 'drug.tcm_patent'), + ('中药饮片', 'Chinese herbal pieces', 'drug.tcm_herb'), + ('生物制品', 'Biological product', 'drug.biological'), + ('疫苗', 'Vaccine', 'drug.vaccine') +) AS v(name_zh, name_en, path) +JOIN category c ON c.path = 'drug';