diff --git a/NewERD.txt b/NewERD.txt deleted file mode 100644 index af89e0a..0000000 --- a/NewERD.txt +++ /dev/null @@ -1,787 +0,0 @@ -//////////////////////////////////////////////////////////// -// PROCUREMENT + INVENTORY SYSTEM -// FINAL INTEGRATED ER (FOR DBDATALYZER / DBDATADIAGRAM.IO) -//////////////////////////////////////////////////////////// - - -//////////////////////////////////////////////////////////// -// ENUMS -//////////////////////////////////////////////////////////// - -enum quote_status { - offered - accepted - arrived - rejected - expired -} - -enum termsheet_status { - offered - accepted - rejected -} - -enum material_status { - active - discontinued - draft -} - -enum attribute_data_type { - number - integer - string - enum - boolean - date -} - -enum discount_type { - none - percent - fixed -} - -enum item_decision_status { - pending - chosen - rejected -} - -enum quote_event_type { - offered - accepted - rejected - arrived - note - edited - expired -} - -enum inventory_transaction_reason { - PURCHASE - WITHDRAWAL - RETURN - TRANSFER_IN - TRANSFER_OUT - DAMAGE - WASTE - LOSS - FOUND - STOCK_COUNT - OTHER -} - - -//////////////////////////////////////////////////////////// -// USERS -//////////////////////////////////////////////////////////// - -Table users { - id uuid [pk, default: `gen_random_uuid()`] - - first_name text [not null] - last_name text [not null] - phone text - - created_at timestamptz [ - not null, - default: `now()` - ] -} - - -//////////////////////////////////////////////////////////// -// CATALOG -//////////////////////////////////////////////////////////// - -Table units { - id integer [pk] - - code varchar [not null, unique] - name_fa varchar - - dimension varchar - si_factor decimal [not null, default: 1.0] - is_base boolean [default: false] -} - - -Table brands { - id uuid [pk, default: `gen_random_uuid()`] - - name text [not null] - country text - - created_at timestamptz [ - not null, - default: `now()` - ] - - indexes { - (name, country) [unique] - } -} - - -Table material_categories { - id uuid [pk, default: `gen_random_uuid()`] - - slug text [not null, unique] - name text [not null] - description text - - is_active boolean [ - not null, - default: true - ] - - created_at timestamptz [ - not null, - default: `now()` - ] - - updated_at timestamptz [ - not null, - default: `now()` - ] -} - - -Table attribute_definitions { - id uuid [pk, default: `gen_random_uuid()`] - - attribute_key text [not null, unique] - label text [not null] - - data_type attribute_data_type [not null] - - unit_id integer [ - ref: > units.id - ] - - enum_values jsonb - - created_at timestamptz [ - not null, - default: `now()` - ] -} - - -Table category_attributes { - id uuid [pk, default: `gen_random_uuid()`] - - category_id uuid [ - not null, - ref: > material_categories.id - ] - - attribute_definition_id uuid [ - not null, - ref: > attribute_definitions.id - ] - - is_required boolean [ - not null, - default: false - ] - - is_filterable boolean [ - not null, - default: false - ] - - conditional_rules jsonb - - sort_order smallint [ - not null, - default: 0 - ] - - indexes { - (category_id, attribute_definition_id) [unique] - } -} - - -Table materials { - id uuid [pk, default: `gen_random_uuid()`] - - category_id uuid [ - not null, - ref: > material_categories.id - ] - - name text [not null] - - // Main unit of the material. - // All inventory quantities are stored in this unit. - canonical_unit_id integer [ - not null, - ref: > units.id - ] - - status material_status [ - not null, - default: 'active' - ] - - created_at timestamptz [ - not null, - default: `now()` - ] - - updated_at timestamptz [ - not null, - default: `now()` - ] - - indexes { - (category_id, name) [unique] - } -} - - -Table brand_materials { - id uuid [pk, default: `gen_random_uuid()`] - - brand_id uuid [ - not null, - ref: > brands.id - ] - - material_id uuid [ - not null, - ref: > materials.id - ] - - catalog_code text - - is_active boolean [ - not null, - default: true - ] - - created_at timestamptz [ - not null, - default: `now()` - ] - - indexes { - (brand_id, material_id) [unique] - } -} - - -Table material_units { - id uuid [pk, default: `gen_random_uuid()`] - - material_id uuid [ - not null, - ref: > materials.id - ] - - // NULL = generic unit - // Non-NULL = brand-specific unit - brand_material_id uuid [ - ref: > brand_materials.id - ] - - unit_id integer [ - not null, - ref: > units.id - ] - - // Converts this unit to materials.canonical_unit_id - conversion_factor decimal(18,6) [ - not null - ] - - is_default boolean [ - not null, - default: false - ] - - indexes { - (material_id, brand_material_id, unit_id) [unique] - } -} - - -Table material_attribute_values { - id uuid [pk, default: `gen_random_uuid()`] - - material_id uuid [ - not null, - ref: > materials.id - ] - - attribute_definition_id uuid [ - not null, - ref: > attribute_definitions.id - ] - - value_number decimal(18,6) - value_string text - value_boolean boolean - value_date date - - indexes { - (material_id, attribute_definition_id) [unique] - } -} - - -//////////////////////////////////////////////////////////// -// SUPPLIERS -//////////////////////////////////////////////////////////// - -Table suppliers { - id uuid [pk, default: `gen_random_uuid()`] - - name text [not null] - location text - phone text - contact_person text - tax_id text - - created_at timestamptz [ - not null, - default: `now()` - ] -} - - -//////////////////////////////////////////////////////////// -// PROJECTS -//////////////////////////////////////////////////////////// - -Table projects { - id uuid [pk, default: `gen_random_uuid()`] - - name text [not null] - description text - start_date date - - created_at timestamptz [ - not null, - default: `now()` - ] -} - - -//////////////////////////////////////////////////////////// -// QUOTATIONS -//////////////////////////////////////////////////////////// - -Table quotes { - id uuid [pk, default: `gen_random_uuid()`] - - supplier_id uuid [ - not null, - ref: > suppliers.id - ] - - project_id uuid [ - ref: > projects.id - ] - - quote_date timestamptz [ - not null, - default: `now()` - ] - - expiry_date date - - accepted_date timestamptz - arrived_date timestamptz - - status quote_status [ - not null, - default: 'offered' - ] - - is_official boolean [ - not null, - default: true - ] - - notes text - - created_at timestamptz [ - not null, - default: `now()` - ] - - updated_at timestamptz [ - not null, - default: `now()` - ] -} - - -Table quote_events { - id uuid [pk, default: `gen_random_uuid()`] - - quote_id uuid [ - not null, - ref: > quotes.id - ] - - event_type quote_event_type [ - not null - ] - - payload jsonb [ - not null, - default: '{}' - ] - - occurred_at timestamptz [ - not null, - default: `now()` - ] - - actor text -} - - -//////////////////////////////////////////////////////////// -// QUOTATION ITEMS -//////////////////////////////////////////////////////////// - -Table line_items { - id uuid [pk, default: `gen_random_uuid()`] - - quote_id uuid [ - not null, - ref: > quotes.id - ] - - material_id uuid [ - not null, - ref: > materials.id - ] - - brand_material_id uuid [ - ref: > brand_materials.id - ] - - unit_id integer [ - not null, - ref: > units.id - ] - - // Ordered / requested quantity - quantity decimal(18,4) [ - not null - ] - - notes text - - created_at timestamptz [ - not null, - default: `now()` - ] -} - - -Table line_item_specs { - id uuid [pk, default: `gen_random_uuid()`] - - line_item_id uuid [ - not null, - ref: > line_items.id - ] - - attribute_definition_id uuid [ - not null, - ref: > attribute_definitions.id - ] - - value_number decimal(18,6) - value_string text - value_boolean boolean - value_date date - - unit_id_at_time integer [ - ref: > units.id - ] - - indexes { - (line_item_id, attribute_definition_id) [unique] - } -} - - -//////////////////////////////////////////////////////////// -// TERMSHEETS -//////////////////////////////////////////////////////////// - -Table termsheets { - id uuid [pk, default: `gen_random_uuid()`] - - quote_id uuid [ - not null, - ref: > quotes.id - ] - - label text [not null] - - status termsheet_status [ - not null, - default: 'offered' - ] - - discount_type discount_type [ - not null, - default: 'none' - ] - - discount_value decimal(18,4) [ - not null, - default: 0 - ] - - created_at timestamptz [ - not null, - default: `now()` - ] -} - - -Table termsheet_schedule_steps { - id uuid [pk, default: `gen_random_uuid()`] - - termsheet_id uuid [ - not null, - ref: > termsheets.id - ] - - step_no smallint [ - not null - ] - - due_date date [ - not null - ] - - amount decimal(18,2) [ - not null - ] - - note text - - indexes { - (termsheet_id, step_no) [unique] - } -} - - -//////////////////////////////////////////////////////////// -// ITEM TERMSHEETS -//////////////////////////////////////////////////////////// - -Table item_termsheets { - id uuid [pk, default: `gen_random_uuid()`] - - line_item_id uuid [ - not null, - ref: > line_items.id - ] - - termsheet_id uuid [ - not null, - ref: > termsheets.id - ] - - unit_price decimal(18,4) [ - not null - ] - - min_order_qty decimal(18,4) - - total_price decimal(18,2) - - indexes { - (line_item_id, termsheet_id) [unique] - } -} - - -//////////////////////////////////////////////////////////// -// ITEM DECISIONS -//////////////////////////////////////////////////////////// - -Table item_decisions { - id uuid [pk, default: `gen_random_uuid()`] - - line_item_id uuid [ - not null, - unique, - ref: - line_items.id - ] - - chosen_item_termsheet_id uuid [ - ref: > item_termsheets.id - ] - - status item_decision_status [ - not null, - default: 'pending' - ] - - adjusted_unit_price decimal(18,4) - - adjusted_notes text - - decided_at timestamptz -} - - -//////////////////////////////////////////////////////////// -// WAREHOUSES -//////////////////////////////////////////////////////////// - -Table warehouses { - id uuid [pk, default: `gen_random_uuid()`] - - project_id uuid [ - not null, - ref: > projects.id - ] - - name text [not null] - - description text - - created_at timestamptz [ - not null, - default: `now()` - ] -} - - -//////////////////////////////////////////////////////////// -// WAREHOUSE ACCESS -//////////////////////////////////////////////////////////// - -Table warehouse_users { - warehouse_id uuid [ - not null, - ref: > warehouses.id - ] - - user_id uuid [ - not null, - ref: > users.id - ] - - indexes { - (warehouse_id, user_id) [pk] - } -} - - -//////////////////////////////////////////////////////////// -// CURRENT INVENTORY SNAPSHOT -//////////////////////////////////////////////////////////// - -Table inventory { - id uuid [pk, default: `gen_random_uuid()`] - - warehouse_id uuid [ - not null, - ref: > warehouses.id - ] - - material_id uuid [ - not null, - ref: > materials.id - ] - - brand_id uuid [ - ref: > brands.id - ] - - item_title text [not null] - - specs jsonb [default: '{}'] - - // SHA256 of sorted canonical specs JSON (or 'default' if empty) - specs_hash varchar(64) [ - not null, - default: 'default' - ] - - quantity decimal(18,6) [ - not null, - default: 0 - ] - - updated_at timestamptz [ - not null, - default: `now()` - ] - - indexes { - (warehouse_id, material_id, brand_id, specs_hash) [unique] - (warehouse_id, item_title) - } -} - - -//////////////////////////////////////////////////////////// -// INVENTORY TRANSACTIONS -//////////////////////////////////////////////////////////// - -Table inventory_transactions { - id uuid [pk, default: `gen_random_uuid()`] - - inventory_id uuid [ - not null, - ref: > inventory.id - ] - - warehouse_id uuid [ - not null, - ref: > warehouses.id - ] - -line_item_id uuid [ - ref: >? line_items.id -] - - quantity decimal(18,6) [ - not null - ] - - reason inventory_transaction_reason [ - not null - ] - - performed_by uuid [ - not null, - ref: > users.id - ] - - transaction_date timestamptz [ - not null, - default: `now()` - ] - - note text - - created_at timestamptz [ - not null, - default: `now()` - ] - - indexes { - (inventory_id, transaction_date) - (warehouse_id, transaction_date) - (inventory_id, line_item_id) - } -} \ No newline at end of file