From cf034af20f06c4a1806830e140b6d5381db6ee67 Mon Sep 17 00:00:00 2001 From: Kevin Hashimoto Date: Mon, 30 Dec 2024 12:36:50 -0800 Subject: [PATCH 1/5] feat: move common seeders to migration file --- .../versions/2024-12-24-07-40_d9cdd9fca0ce.py | 567 +++++++++ backend/lcfs/db/seeders/common/__init__.py | 0 .../common/admin_adjustment_status_seeder.py | 58 - .../common/allocation_agreement_seeder.py | 56 - .../common/compliance_period_seeder.py | 190 --- .../common/compliance_report_status_seeder.py | 66 - .../db/seeders/common/end_user_type_seeder.py | 52 - .../db/seeders/common/fuel_data_seeder.py | 113 -- .../initiative_agreement_status_seeder.py | 58 - .../db/seeders/common/notifications_seeder.py | 208 ---- .../common/organization_status_seeder.py | 64 - .../common/organization_type_seeder.py | 61 - backend/lcfs/db/seeders/common/role_seeder.py | 116 -- .../db/seeders/common/seed_fuel_data.json | 1098 ----------------- .../common/transfer_categories_seeder.py | 49 - .../seeders/common/transfer_status_seeder.py | 104 -- backend/lcfs/db/seeders/common_seeder.py | 102 -- backend/lcfs/db/seeders/seed_database.py | 1 - 18 files changed, 567 insertions(+), 2396 deletions(-) create mode 100644 backend/lcfs/db/migrations/versions/2024-12-24-07-40_d9cdd9fca0ce.py delete mode 100644 backend/lcfs/db/seeders/common/__init__.py delete mode 100644 backend/lcfs/db/seeders/common/admin_adjustment_status_seeder.py delete mode 100644 backend/lcfs/db/seeders/common/allocation_agreement_seeder.py delete mode 100644 backend/lcfs/db/seeders/common/compliance_period_seeder.py delete mode 100644 backend/lcfs/db/seeders/common/compliance_report_status_seeder.py delete mode 100644 backend/lcfs/db/seeders/common/end_user_type_seeder.py delete mode 100644 backend/lcfs/db/seeders/common/fuel_data_seeder.py delete mode 100644 backend/lcfs/db/seeders/common/initiative_agreement_status_seeder.py delete mode 100644 backend/lcfs/db/seeders/common/notifications_seeder.py delete mode 100644 backend/lcfs/db/seeders/common/organization_status_seeder.py delete mode 100644 backend/lcfs/db/seeders/common/organization_type_seeder.py delete mode 100644 backend/lcfs/db/seeders/common/role_seeder.py delete mode 100644 backend/lcfs/db/seeders/common/seed_fuel_data.json delete mode 100644 backend/lcfs/db/seeders/common/transfer_categories_seeder.py delete mode 100644 backend/lcfs/db/seeders/common/transfer_status_seeder.py delete mode 100644 backend/lcfs/db/seeders/common_seeder.py diff --git a/backend/lcfs/db/migrations/versions/2024-12-24-07-40_d9cdd9fca0ce.py b/backend/lcfs/db/migrations/versions/2024-12-24-07-40_d9cdd9fca0ce.py new file mode 100644 index 000000000..e1a57b653 --- /dev/null +++ b/backend/lcfs/db/migrations/versions/2024-12-24-07-40_d9cdd9fca0ce.py @@ -0,0 +1,567 @@ +"""move common seeders to migrations + +Revision ID: d9cdd9fca0ce +Revises: 5fbcb508c1be +Create Date: 2024-12-24 07:40:08.332121 +""" +from alembic import op +import sqlalchemy as sa +from datetime import datetime + +# revision identifiers, used by Alembic. +revision = "d9cdd9fca0ce" +down_revision = "5fbcb508c1be" +branch_labels = None +depends_on = None + + +def upgrade() -> None: + # 1. Compliance Periods + dates = [(year, f"{year}-01-01", f"{year}-12-31") + for year in range(2010, 2033)] + for i, (year, start_date, end_date) in enumerate(dates, 1): + op.execute(f""" + INSERT INTO compliance_period ( + compliance_period_id, description, display_order, + effective_date, expiration_date, effective_status + ) + VALUES ( + {i}, '{year}', {i}, + '{start_date}', '{end_date}', TRUE + ) + ON CONFLICT (compliance_period_id) DO NOTHING; + """) + + # 2. Organization Types + op.execute(""" + INSERT INTO organization_type (organization_type_id, org_type, description) + VALUES + (1, 'fuel_supplier', 'Fuel Supplier'), + (2, 'electricity_supplier', 'Electricity Supplier'), + (3, 'broker', 'Broker'), + (4, 'utilities', 'Utilities (local or public)') + ON CONFLICT (organization_type_id) DO NOTHING; + """) + + # 3. Organization Statuses + op.execute(""" + INSERT INTO organization_status (organization_status_id, status, description) + VALUES + (1, 'Unregistered', 'Unregistered'), + (2, 'Registered', 'Registered'), + (3, 'Suspended', 'Suspended'), + (4, 'Canceled', 'Canceled') + ON CONFLICT (organization_status_id) DO NOTHING; + """) + + # 4. Roles + op.execute(""" + INSERT INTO role (role_id, name, description, is_government_role, display_order) + VALUES + (1, 'GOVERNMENT', 'Identifies a government user in the system.', TRUE, 1), + (2, 'SUPPLIER', 'Identifies a supplier user in the system.', FALSE, 2), + (3, 'ADMINISTRATOR', 'Can add/edit IDIR users and assign roles, add/edit organizations, BCeID users, and assign roles', TRUE, 3), + (4, 'ANALYST', 'Can make recommendations on transfers, transactions, and compliance reports, manage file submissions, and add/edit fuel codes', TRUE, 4), + (5, 'COMPLIANCE_MANAGER', 'Can make recommendations on compliance reports', TRUE, 5), + (6, 'DIRECTOR', 'Can assess compliance reports and approve transactions', TRUE, 6), + (7, 'MANAGE_USERS', 'Can add/edit BCeID users and assign roles', FALSE, 7), + (8, 'TRANSFER', 'Can create/save transfers and submit files', FALSE, 8), + (9, 'COMPLIANCE_REPORTING', 'Can create/save compliance reports and submit files', FALSE, 9), + (10, 'SIGNING_AUTHORITY', 'Can sign and submit compliance reports to government and transfers to trade partners/government', FALSE, 10), + (11, 'READ_ONLY', 'Can view transactions, compliance reports, and files', FALSE, 11) + ON CONFLICT (role_id) DO NOTHING; + """) + + # 5. Transfer Statuses + op.execute(""" + INSERT INTO transfer_status (transfer_status_id, status, visible_to_transferor, visible_to_transferee, visible_to_government) + VALUES + (1, 'Draft', TRUE, FALSE, FALSE), + (2, 'Deleted', FALSE, FALSE, FALSE), + (3, 'Sent', TRUE, TRUE, FALSE), + (4, 'Submitted', TRUE, TRUE, TRUE), + (5, 'Recommended', TRUE, TRUE, TRUE), + (6, 'Recorded', TRUE, TRUE, TRUE), + (7, 'Refused', TRUE, TRUE, TRUE), + (8, 'Declined', TRUE, TRUE, FALSE), + (9, 'Rescinded', TRUE, TRUE, TRUE) + ON CONFLICT (transfer_status_id) DO NOTHING; + """) + + # 6. Transfer Categories + op.execute(""" + INSERT INTO transfer_category (transfer_category_id, category, effective_status) + VALUES + (1, 'A', TRUE), + (2, 'B', TRUE), + (3, 'C', TRUE), + (4, 'D', TRUE) + ON CONFLICT (transfer_category_id) DO NOTHING; + """) + + # 7. Admin Adjustment Statuses + op.execute(""" + INSERT INTO admin_adjustment_status (admin_adjustment_status_id, status) + VALUES + (1, 'Draft'), + (2, 'Recommended'), + (3, 'Approved'), + (4, 'Deleted') + ON CONFLICT (admin_adjustment_status_id) DO NOTHING; + """) + + # 8. Initiative Agreement Statuses + op.execute(""" + INSERT INTO initiative_agreement_status (initiative_agreement_status_id, status) + VALUES + (1, 'Draft'), + (2, 'Recommended'), + (3, 'Approved'), + (4, 'Deleted') + ON CONFLICT (initiative_agreement_status_id) DO NOTHING; + """) + + # 9. Static Fuel Data - Reordered for dependencies + # Unit of Measures first + op.execute(""" + INSERT INTO unit_of_measure (uom_id, name, description) + VALUES + (1, 'MJ/L', 'Megajoules per litre'), + (2, 'MJ/kWh', 'Megajoules per kilowatt hour'), + (3, 'MJ/m³', 'Megajoules per cubic metre'), + (4, 'MJ/kg', 'Megajoules per kilogram'), + (5, 'gCO²e/MJ', 'grams of carbon dioxide equivalent per megajoule') + ON CONFLICT (uom_id) DO NOTHING; + """) + + # End Use Types + op.execute(""" + INSERT INTO end_use_type (end_use_type_id, type, intended_use) + VALUES + (1, 'Light duty motor vehicles', TRUE), + (2, 'Other or unknown', FALSE), + (3, 'Fuel cell vehicle', FALSE), + (4, 'Battery bus', TRUE), + (5, 'Battery truck', TRUE), + (6, 'Cargo handling equipment', TRUE), + (7, 'Fixed guiderail', TRUE), + (8, 'Ground support equipment', TRUE), + (9, 'Heavy forklift', TRUE), + (10, 'Shore power', TRUE), + (11, 'Trolley bus', TRUE), + (12, 'Compression-ignition engine', FALSE), + (13, 'Other', TRUE), + (14, 'Aircraft', TRUE), + (15, 'Compression-ignition engine- Marine, general', TRUE), + (16, 'Compression-ignition engine- Marine, operated within 51 to 75% of load range', TRUE), + (17, 'Compression-ignition engine- Marine, operated within 76 to 100% of load range', TRUE), + (18, 'Compression-ignition engine- Marine, with methane slip reduction kit- General', TRUE), + (19, 'Compression-ignition engine- Marine, with methane slip reduction kit- Operated within 26 to 75% of load range', TRUE), + (20, 'Compression-ignition engine- Marine, with methane slip reduction kit- Operated within 76 to 100% of load range', TRUE), + (21, 'Compression-ignition engine- Marine, unknown whether kit is installed or average operating load range', TRUE), + (22, 'Unknown engine type', TRUE), + (23, 'Other (i.e. road transportation)', TRUE) + ON CONFLICT (end_use_type_id) DO NOTHING; + + """) + + # Energy Effectiveness Ratios + op.execute(""" + INSERT INTO energy_effectiveness_ratio (eer_id, end_use_type_id, ratio, effective_status) + VALUES + (1, 1, 3.4, TRUE), + (2, 2, 1.0, TRUE), + (3, 3, 2.5, TRUE), + (4, 4, 4.4, TRUE), + (5, 5, 4.4, TRUE), + (6, 6, 2.7, TRUE), + (7, 7, 2.9, TRUE), + (8, 8, 2.7, TRUE), + (9, 9, 2.7, TRUE), + (10, 10, 2.7, TRUE), + (11, 11, 2.9, TRUE), + (12, 12, 1.0, TRUE), + (13, 13, 1.0, TRUE), + (14, 14, 1.0, TRUE), + (15, 15, 1.0, TRUE), + (16, 16, 1.0, TRUE), + (17, 17, 1.0, TRUE), + (18, 18, 1.0, TRUE), + (19, 19, 1.0, TRUE), + (20, 20, 1.0, TRUE), + (21, 21, 1.0, TRUE), + (22, 22, 1.0, TRUE), + (23, 23, 1.0, TRUE) + ON CONFLICT (eer_id) DO NOTHING; + """) + + # Provision Acts + op.execute(""" + INSERT INTO provision_of_the_act (provision_of_the_act_id, name, description, effective_status) + VALUES + (1, 'Prescribed carbon intensity - section 19 (a)', 'Prescribed carbon intensity - section 19 (a)', TRUE), + (2, 'Fuel code - section 19 (b) (i)', 'Fuel code - section 19 (b) (i)', TRUE), + (3, 'Default carbon intensity - section 19 (b) (ii)', 'Default carbon intensity - section 19 (b) (ii)', TRUE) + ON CONFLICT (provision_of_the_act_id) DO NOTHING; + """) + + # Fuel Types + op.execute(""" + INSERT INTO fuel_type (fuel_type_id, fuel_type, fossil_derived, other_uses_fossil_derived, + provision_1_id, provision_2_id, default_carbon_intensity, units, unrecognized) + VALUES + (1, 'Biodiesel', FALSE, FALSE, 2, 3, 100.21, 'Litres', FALSE), + (2, 'CNG', FALSE, TRUE, 2, 3, 63.91, 'Cubic_metres', FALSE), + (3, 'Electricity', FALSE, TRUE, 2, 3, 12.14, 'Kilowatt_hour', FALSE), + (4, 'Ethanol', FALSE, FALSE, 2, 3, 93.67, 'Litres', FALSE), + (5, 'HDRD', FALSE, FALSE, 2, 3, 100.21, 'Litres', FALSE), + (6, 'Hydrogen', FALSE, TRUE, 2, 3, 123.96, 'Kilograms', FALSE), + (7, 'LNG', FALSE, TRUE, 2, 3, 90.11, 'Kilograms', FALSE), + (11, 'Alternative jet fuel', FALSE, FALSE, 2, 3, 88.83, 'Litres', FALSE), + (13, 'Propane', FALSE, TRUE, 2, 3, 79.87, 'Litres', FALSE), + (14, 'Renewable gasoline', FALSE, FALSE, 2, 3, 93.67, 'Litres', FALSE), + (15, 'Renewable naphtha', FALSE, FALSE, 2, 3, 93.67, 'Litres', FALSE), + (16, 'Fossil-derived diesel', TRUE, TRUE, 1, NULL, 94.38, 'Litres', FALSE), + (17, 'Fossil-derived gasoline', TRUE, TRUE, 1, NULL, 93.67, 'Litres', FALSE), + (18, 'Fossil-derived jet fuel', TRUE, TRUE, 1, NULL, 88.83, 'Litres', FALSE), + (19, 'Other', FALSE, FALSE, 2, 3, 0, 'Litres', TRUE), + (20, 'Other diesel', FALSE, FALSE, 1, NULL, 100.21, 'Litres', FALSE) + ON CONFLICT (fuel_type_id) DO NOTHING; + """) + + # Now Additional Carbon Intensities + op.execute(""" + INSERT INTO additional_carbon_intensity (additional_uci_id, fuel_type_id, uom_id, end_use_type_id, intensity) + VALUES + (1, 7, 5, NULL, 0), + (2, NULL, 5, NULL, 0), + (3, 7, 5, 15, 27.3), + (4, 7, 5, 16, 17.8), + (5, 7, 5, 17, 12.2), + (6, 7, 5, 18, 10.6), + (7, 7, 5, 19, 8.4), + (8, 7, 5, 20, 8.0), + (9, 7, 5, 21, 27.3), + (10, 7, 5, 22, 27.3), + (11, 7, 5, 23, 0) + ON CONFLICT (additional_uci_id) DO NOTHING; + """) + + # Energy Densities + op.execute(""" + INSERT INTO energy_density (energy_density_id, fuel_type_id, uom_id, density) + VALUES + (1, 17, 1, 34.69), + (2, 4, 1, 23.58), + (3, 14, 1, 34.69), + (4, 15, 1, 34.51), + (5, 16, 1, 38.65), + (6, 1, 1, 35.40), + (7, 5, 1, 37.89), + (9, 18, 1, 37.40), + (10, 11, 1, 36.00), + (11, 3, 2, 3.60), + (12, 6, 2, 141.76), + (13, 13, 1, 25.62), + (14, 2, 3, 38.27), + (15, 7, 4, 53.54), + (16, 20, 1, 36.51) + ON CONFLICT (energy_density_id) DO NOTHING; + """) + + # Fuel Categories + op.execute(""" + INSERT INTO fuel_category (fuel_category_id, category, description, default_carbon_intensity, effective_status) + VALUES + (1, 'Gasoline', 'Gasoline', 93.67, TRUE), + (2, 'Diesel', 'Diesel', 100.21, TRUE), + (3, 'Jet fuel', 'Jet fuel', 88.83, TRUE) + ON CONFLICT (fuel_category_id) DO NOTHING; + """) + + # Target Carbon Intensities + op.execute(""" + INSERT INTO target_carbon_intensity ( + target_carbon_intensity_id, + compliance_period_id, + fuel_category_id, + target_carbon_intensity, + reduction_target_percentage, + effective_status + ) + VALUES + (1, 15, 1, 78.68, 16.0, TRUE), + (2, 16, 1, 76.53, 18.3, TRUE), + (3, 17, 1, 74.37, 20.6, TRUE), + (4, 18, 1, 72.13, 23.0, TRUE), + (5, 19, 1, 69.97, 25.3, TRUE), + (6, 20, 1, 67.72, 27.7, TRUE), + (7, 21, 1, 65.57, 30.0, TRUE), + (8, 15, 2, 79.28, 16.0, TRUE), + (9, 16, 2, 77.11, 18.3, TRUE), + (10, 17, 2, 74.94, 20.6, TRUE), + (11, 18, 2, 72.67, 23.0, TRUE), + (12, 19, 2, 70.50, 25.3, TRUE), + (13, 20, 2, 68.24, 27.7, TRUE), + (14, 21, 2, 66.07, 30.0, TRUE), + (15, 15, 3, 88.83, 0.0, TRUE), + (16, 16, 3, 88.83, 0.0, TRUE), + (17, 17, 3, 87.05, 2.0, TRUE), + (18, 18, 3, 85.28, 4.0, TRUE), + (19, 19, 3, 83.50, 6.0, TRUE), + (20, 20, 3, 81.72, 8.0, TRUE), + (21, 21, 3, 79.95, 10.0, TRUE) + ON CONFLICT (target_carbon_intensity_id) DO NOTHING; + """) + + # Fuel Instances + op.execute(""" + INSERT INTO fuel_instance (fuel_instance_id, fuel_type_id, fuel_category_id) + VALUES + (1, 1, 2), + (2, 2, 1), + (3, 2, 2), + (4, 3, 1), + (5, 3, 2), + (6, 3, 3), + (7, 4, 1), + (8, 5, 2), + (9, 6, 1), + (10, 6, 2), + (11, 6, 3), + (12, 7, 2), + (16, 11, 3), + (18, 13, 1), + (19, 13, 2), + (20, 14, 1), + (21, 15, 1), + (22, 16, 2), + (23, 17, 1), + (24, 18, 3), + (25, 19, 1), + (26, 19, 2), + (27, 19, 3), + (28, 20, 2) + ON CONFLICT (fuel_instance_id) DO NOTHING; + """) + + # Transport Modes + op.execute(""" + INSERT INTO transport_mode (transport_mode_id, transport_mode) + VALUES + (1, 'Truck'), + (2, 'Rail'), + (3, 'Marine-domestic'), + (4, 'Adjacent'), + (5, 'Pipeline') + ON CONFLICT (transport_mode_id) DO NOTHING; + """) + + # Fuel Code Prefixes + op.execute(""" + INSERT INTO fuel_code_prefix (fuel_code_prefix_id, prefix) + VALUES + (1, 'BCLCF'), + (2, 'PROXY') + ON CONFLICT (fuel_code_prefix_id) DO NOTHING; + """) + + # Fuel Code Statuses + op.execute(""" + INSERT INTO fuel_code_status (fuel_code_status_id, status, description, display_order) + VALUES + (1, 'Draft', 'Initial state of the fuel code', 1), + (2, 'Approved', 'Fuel code has been approved', 2), + (3, 'Deleted', 'Fuel code has been deleted', 3) + ON CONFLICT (fuel_code_status_id) DO NOTHING; + """) + + # Level of Equipment + op.execute(""" + INSERT INTO level_of_equipment (level_of_equipment_id, name, display_order) + VALUES + (1, 'Level 3 - Direct current fast charging', 1), + (2, 'Level 2 - High voltage, operating above level 1', 2), + (3, 'Level 1 - Low voltage, operating at 120V AC or less', 3), + (4, 'Other - Additional information provided in notes field', 4) + ON CONFLICT (level_of_equipment_id) DO NOTHING; + """) + + # Fuel Measurement Types + op.execute(""" + INSERT INTO fuel_measurement_type (fuel_measurement_type_id, type, display_order) + VALUES + (1, 'Separate utility meter', 1), + (2, 'Equipment meter (remote access)', 2), + (3, 'Equipment meter (physical access)', 3), + (4, 'No meter or estimated', 4) + ON CONFLICT (fuel_measurement_type_id) DO NOTHING; + """) + + # 10. Compliance Report Statuses + op.execute(""" + INSERT INTO compliance_report_status (compliance_report_status_id, status, effective_status) + VALUES + (1, 'Draft', TRUE), + (2, 'Submitted', TRUE), + (3, 'Recommended_by_analyst', TRUE), + (4, 'Recommended_by_manager', TRUE), + (5, 'Assessed', TRUE), + (6, 'ReAssessed', TRUE) + ON CONFLICT (compliance_report_status_id) DO NOTHING; + """) + + # 11. Allocation Transaction Types + op.execute(""" + INSERT INTO allocation_transaction_type ( + allocation_transaction_type_id, type, description, + display_order, effective_date, effective_status + ) + VALUES + (1, 'Allocated from', 'Fuel allocated from another supplier under an allocation agreement', 1, '2012-01-01', TRUE), + (2, 'Allocated to', 'Fuel allocated to another supplier under an allocation agreement', 2, '2012-01-01', TRUE) + ON CONFLICT (allocation_transaction_type_id) DO NOTHING; + """) + + # 12. End User Types + op.execute(""" + INSERT INTO end_user_type (type_name, intended_use) + VALUES + ('Multi-unit residential building', TRUE), + ('Fleet', TRUE), + ('Public', TRUE), + ('Employee', TRUE) + ON CONFLICT (type_name) DO NOTHING; + """) + + # 13. Notification Types + op.execute(""" + INSERT INTO notification_type (notification_type_id, name, description, email_content, create_user, update_user) + VALUES + (1, 'BCEID__COMPLIANCE_REPORT__DIRECTOR_ASSESSMENT', 'Director assessed a compliance report or supplemental report.', 'Email content', 'system', 'system'), + (2, 'BCEID__INITIATIVE_AGREEMENT__DIRECTOR_APPROVAL', 'Director approved the initiative agreement or transaction', 'Email content', 'system', 'system'), + (3, 'BCEID__TRANSFER__DIRECTOR_DECISION', 'Director recorded or refused a transfer request', 'Email content', 'system', 'system'), + (4, 'BCEID__TRANSFER__PARTNER_ACTIONS', 'A transfer partner took action (proposed, declined, rescinded, or signed & submitted) on a transfer request', 'Email content', 'system', 'system'), + (5, 'IDIR_ANALYST__COMPLIANCE_REPORT__DIRECTOR_DECISION', 'Director assessed compliance report', 'Email content', 'system', 'system'), + (6, 'IDIR_ANALYST__COMPLIANCE_REPORT__MANAGER_RECOMMENDATION', 'Compliance manager recommended action on the compliance report.', 'Email content', 'system', 'system'), + (7, 'IDIR_ANALYST__COMPLIANCE_REPORT__SUBMITTED_FOR_REVIEW', 'Compliance report submitted for government analyst review or returned by compliance manager', 'Email content', 'system', 'system'), + (8, 'IDIR_ANALYST__INITIATIVE_AGREEMENT__RETURNED_TO_ANALYST', 'Director approved/returned the initiative agreement to the analyst', 'Email content', 'system', 'system'), + (9, 'IDIR_ANALYST__TRANSFER__DIRECTOR_RECORDED', 'Director recorded or refused a transfer request', 'Email content', 'system', 'system'), + (10, 'IDIR_ANALYST__TRANSFER__RESCINDED_ACTION', 'A transfer request was rescinded by a transfer partner', 'Email content', 'system', 'system'), + (11, 'IDIR_ANALYST__TRANSFER__SUBMITTED_FOR_REVIEW', 'Transfer request submitted for government analyst review', 'Email content', 'system', 'system'), + (12, 'IDIR_COMPLIANCE_MANAGER__COMPLIANCE_REPORT__ANALYST_RECOMMENDATION', 'Analyst recommendation on the compliance report or returned by the director', 'Email content', 'system', 'system'), + (13, 'IDIR_COMPLIANCE_MANAGER__COMPLIANCE_REPORT__DIRECTOR_ASSESSMENT', 'Director assessed a compliance report', 'Email content', 'system', 'system'), + (14, 'IDIR_COMPLIANCE_MANAGER__COMPLIANCE_REPORT__SUBMITTED_FOR_REVIEW', 'Compliance report submitted for government analyst review', 'Email content', 'system', 'system'), + (15, 'IDIR_DIRECTOR__COMPLIANCE_REPORT__MANAGER_RECOMMENDATION', 'Compliance manager recommended action on the compliance report', 'Email content', 'system', 'system'), + (16, 'IDIR_DIRECTOR__INITIATIVE_AGREEMENT__ANALYST_RECOMMENDATION', 'Analyst recommendation provided for the initiative agreement', 'Email content', 'system', 'system'), + (17, 'IDIR_DIRECTOR__TRANSFER__ANALYST_RECOMMENDATION', 'Analyst recommendation provided for the transfer request', 'Email content', 'system', 'system') + ON CONFLICT (notification_type_id) DO NOTHING; + """) + + # 14. Notification Channels + op.execute(""" + INSERT INTO notification_channel (notification_channel_id, channel_name, enabled, subscribe_by_default) + VALUES + (1, 'EMAIL', TRUE, TRUE), + (2, 'IN_APP', TRUE, FALSE) + ON CONFLICT (notification_channel_id) DO NOTHING; + """) + + # Update sequences + sequence_mappings = { + 'transfer_status': 'transfer_status_id', + 'transfer_category': 'transfer_category_id', + 'role': 'role_id', + 'organization_type': 'organization_type_id', + 'organization_status': 'organization_status_id', + 'initiative_agreement_status': 'initiative_agreement_status_id', + 'compliance_period': 'compliance_period_id', + 'admin_adjustment_status': 'admin_adjustment_status_id', + 'notification_channel': 'notification_channel_id', + 'notification_type': 'notification_type_id', + 'end_user_type': 'end_user_type_id', + 'compliance_report_status': 'compliance_report_status_id', + 'allocation_transaction_type': 'allocation_transaction_type_id', + 'provision_of_the_act': 'provision_of_the_act_id', + 'transport_mode': 'transport_mode_id', + 'fuel_code_prefix': 'fuel_code_prefix_id', + 'fuel_code_status': 'fuel_code_status_id', + 'fuel_category': 'fuel_category_id', + 'fuel_type': 'fuel_type_id', + 'unit_of_measure': 'uom_id', # Both column and sequence use uom_id + 'additional_carbon_intensity': 'additional_uci_id', + 'energy_effectiveness_ratio': 'eer_id', + 'energy_density': 'energy_density_id', + 'target_carbon_intensity': 'target_carbon_intensity_id', + 'fuel_instance': 'fuel_instance_id', + 'level_of_equipment': 'level_of_equipment_id', + 'fuel_measurement_type': 'fuel_measurement_type_id' + } + + for table, id_column in sequence_mappings.items(): + if table == 'unit_of_measure': + # Special case for unit_of_measure table + op.execute(f""" + SELECT setval('unit_of_measure_uom_id_seq', + (SELECT MAX(uom_id) FROM unit_of_measure), true); + """) + else: + op.execute(f""" + SELECT setval('{table}_{id_column}_seq', + (SELECT MAX({id_column}) FROM {table}), true); + """) + + +def downgrade() -> None: + # Clear all seeded data in reverse order of creation, respecting foreign key constraints + table_groups = [ + # Group 1 - Most dependent tables (records with multiple foreign keys) + [ + 'fuel_instance', # Depends on fuel_type and fuel_category + 'target_carbon_intensity', # Depends on compliance_period and fuel_category + 'additional_carbon_intensity', # Depends on fuel_type and end_use_type + 'energy_density', # Depends on fuel_type and uom + 'energy_effectiveness_ratio', # Added here since it depends on end_use_type + 'fuel_code', # If exists, depends on several tables + ], + + # Group 2 - Tables with single foreign key dependencies + [ + 'notification_channel', + 'notification_type', + 'end_user_type', + 'allocation_transaction_type', + 'compliance_report_status', + 'fuel_measurement_type', + 'level_of_equipment', + ], + + # Group 3 - Core reference tables with dependencies + [ + 'fuel_type', # Depends on provision_of_the_act + 'fuel_category', + 'transport_mode', + 'fuel_code_prefix', + 'fuel_code_status', + 'end_use_type', + ], + + # Group 4 - Base reference tables (no dependencies) + [ + 'unit_of_measure', + 'provision_of_the_act', + 'initiative_agreement_status', + 'admin_adjustment_status', + 'transfer_category', + 'transfer_status', + 'role', + 'organization_status', + 'organization_type', + 'compliance_period' + ] + ] + + # Execute TRUNCATE for each group + for group in table_groups: + tables_list = ', '.join(group) + op.execute(f"TRUNCATE TABLE {tables_list} CASCADE;") diff --git a/backend/lcfs/db/seeders/common/__init__.py b/backend/lcfs/db/seeders/common/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/backend/lcfs/db/seeders/common/admin_adjustment_status_seeder.py b/backend/lcfs/db/seeders/common/admin_adjustment_status_seeder.py deleted file mode 100644 index 2e847b80e..000000000 --- a/backend/lcfs/db/seeders/common/admin_adjustment_status_seeder.py +++ /dev/null @@ -1,58 +0,0 @@ -import structlog -from sqlalchemy import select -from lcfs.db.models.admin_adjustment.AdminAdjustmentStatus import ( - AdminAdjustmentStatus, - AdminAdjustmentStatusEnum, -) - -logger = structlog.get_logger(__name__) - - -async def seed_admin_adjustment_statuses(session): - """ - Seeds the admin adjustment statuses into the database, if they do not already exist. - - Args: - session: The database session for committing the new records. - """ - admin_adjustment_statuses_to_seed = [ - { - "admin_adjustment_status_id": 1, - "status": AdminAdjustmentStatusEnum.Draft, - }, - { - "admin_adjustment_status_id": 2, - "status": AdminAdjustmentStatusEnum.Recommended, - }, - { - "admin_adjustment_status_id": 3, - "status": AdminAdjustmentStatusEnum.Approved, - }, - { - "admin_adjustment_status_id": 4, - "status": AdminAdjustmentStatusEnum.Deleted, - }, - ] - - try: - for status_data in admin_adjustment_statuses_to_seed: - exists = await session.execute( - select(AdminAdjustmentStatus).where( - AdminAdjustmentStatus.status == status_data["status"] - ) - ) - if not exists.scalars().first(): - status = AdminAdjustmentStatus(**status_data) - session.add(status) - - except Exception as e: - context = { - "function": "seed_admin_adjustment_statuses", - } - logger.error( - "Error occurred while seeding admin adjustment statuses", - error=str(e), - exc_info=e, - **context, - ) - raise diff --git a/backend/lcfs/db/seeders/common/allocation_agreement_seeder.py b/backend/lcfs/db/seeders/common/allocation_agreement_seeder.py deleted file mode 100644 index e48a57227..000000000 --- a/backend/lcfs/db/seeders/common/allocation_agreement_seeder.py +++ /dev/null @@ -1,56 +0,0 @@ -import structlog -from sqlalchemy import select -from datetime import datetime -from lcfs.db.models.compliance.AllocationTransactionType import ( - AllocationTransactionType, -) - -logger = structlog.get_logger(__name__) - - -async def seed_allocation_transaction_types(session): - """ - Seeds the allocation transaction types into the database, if they do not already exist. - - Args: - session: The database session for committing the new records. - """ - allocation_transaction_types_to_seed = [ - { - "allocation_transaction_type_id": 1, - "type": "Allocated from", - "description": "Fuel allocated from another supplier under an allocation agreement", - "display_order": 1, - "effective_date": datetime.strptime("2012-01-01", "%Y-%m-%d").date(), - }, - { - "allocation_transaction_type_id": 2, - "type": "Allocated to", - "description": "Fuel allocated to another supplier under an allocation agreement", - "display_order": 2, - "effective_date": datetime.strptime("2012-01-01", "%Y-%m-%d").date(), - }, - ] - - try: - for type_data in allocation_transaction_types_to_seed: - exists = await session.execute( - select(AllocationTransactionType).where( - AllocationTransactionType.type == type_data["type"] - ) - ) - if not exists.scalars().first(): - transaction_type = AllocationTransactionType(**type_data) - session.add(transaction_type) - - except Exception as e: - context = { - "function": "seed_allocation_transaction_types", - } - logger.error( - "Error occurred while seeding allocation transaction types", - error=str(e), - exc_info=e, - **context, - ) - raise diff --git a/backend/lcfs/db/seeders/common/compliance_period_seeder.py b/backend/lcfs/db/seeders/common/compliance_period_seeder.py deleted file mode 100644 index 6c0f36487..000000000 --- a/backend/lcfs/db/seeders/common/compliance_period_seeder.py +++ /dev/null @@ -1,190 +0,0 @@ -import structlog -from sqlalchemy import select -from datetime import datetime -from lcfs.db.models.compliance.CompliancePeriod import CompliancePeriod - -logger = structlog.get_logger(__name__) - - -async def seed_compliance_periods(session): - """ - Seeds the compliance periods into the database, if they do not already exist. - - Args: - session: The database session for committing the new records. - """ - - compliance_periods_to_seed = [ - { - "compliance_period_id": 1, - "description": "2010", - "display_order": 1, - "effective_date": datetime.strptime("2010-01-01", "%Y-%m-%d").date(), - "expiration_date": datetime.strptime("2010-12-31", "%Y-%m-%d").date(), - }, - { - "compliance_period_id": 2, - "description": "2011", - "display_order": 2, - "effective_date": datetime.strptime("2011-01-01", "%Y-%m-%d").date(), - "expiration_date": datetime.strptime("2011-12-31", "%Y-%m-%d").date(), - }, - { - "compliance_period_id": 3, - "description": "2012", - "display_order": 3, - "effective_date": datetime.strptime("2012-01-01", "%Y-%m-%d").date(), - "expiration_date": datetime.strptime("2012-12-31", "%Y-%m-%d").date(), - }, - { - "compliance_period_id": 4, - "description": "2013", - "display_order": 4, - "effective_date": datetime.strptime("2013-01-01", "%Y-%m-%d").date(), - "expiration_date": datetime.strptime("2013-12-31", "%Y-%m-%d").date(), - }, - { - "compliance_period_id": 5, - "description": "2014", - "display_order": 5, - "effective_date": datetime.strptime("2014-01-01", "%Y-%m-%d").date(), - "expiration_date": datetime.strptime("2014-12-31", "%Y-%m-%d").date(), - }, - { - "compliance_period_id": 6, - "description": "2015", - "display_order": 6, - "effective_date": datetime.strptime("2015-01-01", "%Y-%m-%d").date(), - "expiration_date": datetime.strptime("2015-12-31", "%Y-%m-%d").date(), - }, - { - "compliance_period_id": 7, - "description": "2016", - "display_order": 7, - "effective_date": datetime.strptime("2016-01-01", "%Y-%m-%d").date(), - "expiration_date": datetime.strptime("2016-12-31", "%Y-%m-%d").date(), - }, - { - "compliance_period_id": 8, - "description": "2017", - "display_order": 8, - "effective_date": datetime.strptime("2017-01-01", "%Y-%m-%d").date(), - "expiration_date": datetime.strptime("2017-12-31", "%Y-%m-%d").date(), - }, - { - "compliance_period_id": 9, - "description": "2018", - "display_order": 9, - "effective_date": datetime.strptime("2018-01-01", "%Y-%m-%d").date(), - "expiration_date": datetime.strptime("2018-12-31", "%Y-%m-%d").date(), - }, - { - "compliance_period_id": 10, - "description": "2019", - "display_order": 10, - "effective_date": datetime.strptime("2019-01-01", "%Y-%m-%d").date(), - "expiration_date": datetime.strptime("2019-12-31", "%Y-%m-%d").date(), - }, - { - "compliance_period_id": 11, - "description": "2020", - "display_order": 11, - "effective_date": datetime.strptime("2020-01-01", "%Y-%m-%d").date(), - "expiration_date": datetime.strptime("2020-12-31", "%Y-%m-%d").date(), - }, - { - "compliance_period_id": 12, - "description": "2021", - "display_order": 12, - "effective_date": datetime.strptime("2021-01-01", "%Y-%m-%d").date(), - "expiration_date": datetime.strptime("2021-12-31", "%Y-%m-%d").date(), - }, - { - "compliance_period_id": 13, - "description": "2022", - "display_order": 13, - "effective_date": datetime.strptime("2022-01-01", "%Y-%m-%d").date(), - "expiration_date": datetime.strptime("2022-12-31", "%Y-%m-%d").date(), - }, - { - "compliance_period_id": 14, - "description": "2023", - "display_order": 14, - "effective_date": datetime.strptime("2023-01-01", "%Y-%m-%d").date(), - "expiration_date": datetime.strptime("2023-12-31", "%Y-%m-%d").date(), - }, - { - "compliance_period_id": 15, - "description": "2024", - "display_order": 15, - "effective_date": datetime.strptime("2024-01-01", "%Y-%m-%d").date(), - "expiration_date": datetime.strptime("2024-12-31", "%Y-%m-%d").date(), - }, - { - "compliance_period_id": 16, - "description": "2025", - "display_order": 16, - "effective_date": datetime.strptime("2025-01-01", "%Y-%m-%d").date(), - "expiration_date": datetime.strptime("2025-12-31", "%Y-%m-%d").date(), - }, - { - "compliance_period_id": 17, - "description": "2026", - "display_order": 17, - "effective_date": datetime.strptime("2026-01-01", "%Y-%m-%d").date(), - "expiration_date": datetime.strptime("2026-12-31", "%Y-%m-%d").date(), - }, - { - "compliance_period_id": 18, - "description": "2027", - "display_order": 18, - "effective_date": datetime.strptime("2027-01-01", "%Y-%m-%d").date(), - "expiration_date": datetime.strptime("2027-12-31", "%Y-%m-%d").date(), - }, - { - "compliance_period_id": 19, - "description": "2028", - "display_order": 19, - "effective_date": datetime.strptime("2028-01-01", "%Y-%m-%d").date(), - "expiration_date": datetime.strptime("2028-12-31", "%Y-%m-%d").date(), - }, - { - "compliance_period_id": 20, - "description": "2029", - "display_order": 20, - "effective_date": datetime.strptime("2029-01-01", "%Y-%m-%d").date(), - "expiration_date": datetime.strptime("2029-12-31", "%Y-%m-%d").date(), - }, - { - "compliance_period_id": 21, - "description": "2030", - "display_order": 21, - "effective_date": datetime.strptime("2030-01-01", "%Y-%m-%d").date(), - "expiration_date": datetime.strptime("2030-12-31", "%Y-%m-%d").date(), - }, - ] - - try: - for compliance_period_data in compliance_periods_to_seed: - # Check if the CompliancePeriod already exists based on the description - exists = await session.execute( - select(CompliancePeriod).where( - CompliancePeriod.description - == compliance_period_data["description"] - ) - ) - if not exists.scalars().first(): - compliance_period = CompliancePeriod(**compliance_period_data) - session.add(compliance_period) - - except Exception as e: - context = { - "function": "seed_compliance_periods", - } - logger.error( - "Error occurred while seeding compliance periods", - error=str(e), - exc_info=e, - **context, - ) - raise diff --git a/backend/lcfs/db/seeders/common/compliance_report_status_seeder.py b/backend/lcfs/db/seeders/common/compliance_report_status_seeder.py deleted file mode 100644 index cf9a7a568..000000000 --- a/backend/lcfs/db/seeders/common/compliance_report_status_seeder.py +++ /dev/null @@ -1,66 +0,0 @@ -import structlog -from sqlalchemy import select -from lcfs.db.models.compliance.ComplianceReportStatus import ( - ComplianceReportStatus, - ComplianceReportStatusEnum, -) - -logger = structlog.get_logger(__name__) - - -async def seed_compliance_report_statuses(session): - """ - Seeds the compliance report statuses into the database, if they do not already exist. - - Args: - session: The database session for committing the new records. - """ - compliance_report_statuses_to_seed = [ - { - "compliance_report_status_id": 1, - "status": ComplianceReportStatusEnum.Draft, - }, - { - "compliance_report_status_id": 2, - "status": ComplianceReportStatusEnum.Submitted, - }, - { - "compliance_report_status_id": 3, - "status": ComplianceReportStatusEnum.Recommended_by_analyst, - }, - { - "compliance_report_status_id": 4, - "status": ComplianceReportStatusEnum.Recommended_by_manager, - }, - { - "compliance_report_status_id": 5, - "status": ComplianceReportStatusEnum.Assessed, - }, - { - "compliance_report_status_id": 6, - "status": ComplianceReportStatusEnum.ReAssessed, - }, - ] - - try: - for status_data in compliance_report_statuses_to_seed: - exists = await session.execute( - select(ComplianceReportStatus).where( - ComplianceReportStatus.status == status_data["status"] - ) - ) - if not exists.scalars().first(): - status = ComplianceReportStatus(**status_data) - session.add(status) - - except Exception as e: - context = { - "function": "seed_compliance_report_statuses", - } - logger.error( - "Error occurred while seeding compliance report statuses", - error=str(e), - exc_info=e, - **context, - ) - raise diff --git a/backend/lcfs/db/seeders/common/end_user_type_seeder.py b/backend/lcfs/db/seeders/common/end_user_type_seeder.py deleted file mode 100644 index d0790f40e..000000000 --- a/backend/lcfs/db/seeders/common/end_user_type_seeder.py +++ /dev/null @@ -1,52 +0,0 @@ -import structlog -from sqlalchemy import select -from sqlalchemy.exc import IntegrityError -from lcfs.db.models.compliance.EndUserType import EndUserType - -logger = structlog.get_logger(__name__) - - -async def seed_end_user_types(session): - """ - Seeds the end_user_type table with predefined values if they do not already exist. - - Args: - session: The database session for committing the new records. - """ - - end_user_types_to_seed = [ - {"type_name": "Multi-unit residential building"}, - {"type_name": "Fleet"}, - {"type_name": "Public"}, - {"type_name": "Employee"}, - ] - - try: - for end_user_type_data in end_user_types_to_seed: - # Check if the EndUserType already exists - exists = await session.execute( - select(EndUserType).where( - EndUserType.type_name == end_user_type_data["type_name"] - ) - ) - if not exists.scalars().first(): - end_user_type = EndUserType(**end_user_type_data) - session.add(end_user_type) - - except IntegrityError as ie: - logger.warning( - "Integrity error while seeding end_user_type", - error=str(ie), - exc_info=ie, - ) - except Exception as e: - context = { - "function": "seed_end_user_types", - } - logger.error( - "Error occurred while seeding end_user_type", - error=str(e), - exc_info=e, - **context, - ) - raise diff --git a/backend/lcfs/db/seeders/common/fuel_data_seeder.py b/backend/lcfs/db/seeders/common/fuel_data_seeder.py deleted file mode 100644 index cbb1ce003..000000000 --- a/backend/lcfs/db/seeders/common/fuel_data_seeder.py +++ /dev/null @@ -1,113 +0,0 @@ -import structlog -import json -from pathlib import Path -from sqlalchemy import select - -# database models -from lcfs.db.models.fuel.EnergyDensity import EnergyDensity -from lcfs.db.models.fuel.AdditionalCarbonIntensity import AdditionalCarbonIntensity -from lcfs.db.models.fuel.EnergyEffectivenessRatio import EnergyEffectivenessRatio -from lcfs.db.models.fuel.EndUseType import EndUseType -from lcfs.db.models.fuel.FuelCategory import FuelCategory -from lcfs.db.models.fuel.FuelCodePrefix import FuelCodePrefix -from lcfs.db.models.fuel.FuelCodeStatus import FuelCodeStatus -from lcfs.db.models.fuel.ProvisionOfTheAct import ProvisionOfTheAct -from lcfs.db.models.fuel.TransportMode import TransportMode -from lcfs.db.models.fuel.UnitOfMeasure import UnitOfMeasure -from lcfs.db.models.fuel.FuelType import FuelType, QuantityUnitsEnum -from lcfs.db.models.fuel.TargetCarbonIntensity import TargetCarbonIntensity -from lcfs.db.models.fuel.FuelInstance import FuelInstance -from lcfs.db.models.compliance import FuelMeasurementType, LevelOfEquipment - -logger = structlog.get_logger(__name__) - -UNITS_MAPPING = { - "L": QuantityUnitsEnum.Litres, - "kg": QuantityUnitsEnum.Kilograms, - "kWh": QuantityUnitsEnum.Kilowatt_hour, - "m³": QuantityUnitsEnum.Cubic_metres, -} - - -async def seed_static_fuel_data(session): - """ - Seeds the static fuel data into the database, if they do not already exist. - - Args: - session: The database session for committing the new records. - """ - try: - with open(Path(__file__).parent / "seed_fuel_data.json") as f_data: - data = json.load(f_data) - - async def add_if_not_exists(model, unique_field, records): - for record in records: - exists = await session.execute( - select(model).where( - getattr(model, unique_field) == record[unique_field] - ) - ) - if not exists.scalars().first(): - session.add(model(**record)) - - # Ensure fuel_type units are correctly formatted - for fuel_type in data["fuel_types"]: - fuel_type["units"] = QuantityUnitsEnum(fuel_type["units"]) - - await add_if_not_exists( - TransportMode, "transport_mode_id", data["transport_modes"] - ) - await add_if_not_exists( - ProvisionOfTheAct, "provision_of_the_act_id", data["provision_acts"] - ) - await add_if_not_exists(FuelType, "fuel_type_id", data["fuel_types"]) - await add_if_not_exists( - FuelCodePrefix, "fuel_code_prefix_id", data["fuel_code_prefixes"] - ) - await add_if_not_exists( - FuelCodeStatus, "fuel_code_status_id", data["fuel_code_statuses"] - ) - await add_if_not_exists( - FuelCategory, "fuel_category_id", data["fuel_categories"] - ) - await add_if_not_exists( - EndUseType, "end_use_type_id", data["end_use_types"] - ) - await add_if_not_exists(UnitOfMeasure, "uom_id", data["unit_of_measures"]) - await add_if_not_exists( - AdditionalCarbonIntensity, "additional_uci_id", data["ucis"] - ) - await add_if_not_exists(EnergyEffectivenessRatio, "eer_id", data["eers"]) - await add_if_not_exists( - EnergyDensity, "energy_density_id", data["energy_densities"] - ) - await add_if_not_exists( - TargetCarbonIntensity, - "target_carbon_intensity_id", - data["target_carbon_intensities"], - ) - await add_if_not_exists( - FuelInstance, "fuel_instance_id", data["fuel_instances"] - ) - await add_if_not_exists( - FuelMeasurementType, - "fuel_measurement_type_id", - data["fuel_measurement_types"], - ) - await add_if_not_exists( - LevelOfEquipment, "level_of_equipment_id", data["levels_of_equipment"] - ) - - f_data.close() - - except Exception as e: - context = { - "function": "seed_static_fuel_data", - } - logger.error( - "Error occurred while seeding static fuel data", - error=str(e), - exc_info=e, - **context, - ) - raise diff --git a/backend/lcfs/db/seeders/common/initiative_agreement_status_seeder.py b/backend/lcfs/db/seeders/common/initiative_agreement_status_seeder.py deleted file mode 100644 index a44518054..000000000 --- a/backend/lcfs/db/seeders/common/initiative_agreement_status_seeder.py +++ /dev/null @@ -1,58 +0,0 @@ -import structlog -from sqlalchemy import select -from lcfs.db.models.initiative_agreement.InitiativeAgreementStatus import ( - InitiativeAgreementStatus, - InitiativeAgreementStatusEnum, -) - -logger = structlog.get_logger(__name__) - - -async def seed_initiative_agreement_statuses(session): - """ - Seeds the initiative agreement statuses into the database, if they do not already exist. - - Args: - session: The database session for committing the new records. - """ - initiative_agreement_statuses_to_seed = [ - { - "initiative_agreement_status_id": 1, - "status": InitiativeAgreementStatusEnum.Draft, - }, - { - "initiative_agreement_status_id": 2, - "status": InitiativeAgreementStatusEnum.Recommended, - }, - { - "initiative_agreement_status_id": 3, - "status": InitiativeAgreementStatusEnum.Approved, - }, - { - "initiative_agreement_status_id": 4, - "status": InitiativeAgreementStatusEnum.Deleted, - }, - ] - - try: - for status_data in initiative_agreement_statuses_to_seed: - exists = await session.execute( - select(InitiativeAgreementStatus).where( - InitiativeAgreementStatus.status == status_data["status"] - ) - ) - if not exists.scalars().first(): - status = InitiativeAgreementStatus(**status_data) - session.add(status) - - except Exception as e: - context = { - "function": "seed_initiative_agreement_statuses", - } - logger.error( - "Error occurred while seeding initiative agreement statuses", - error=str(e), - exc_info=e, - **context, - ) - raise diff --git a/backend/lcfs/db/seeders/common/notifications_seeder.py b/backend/lcfs/db/seeders/common/notifications_seeder.py deleted file mode 100644 index 363ae6c98..000000000 --- a/backend/lcfs/db/seeders/common/notifications_seeder.py +++ /dev/null @@ -1,208 +0,0 @@ -import structlog -from sqlalchemy import select -from sqlalchemy.exc import IntegrityError -from lcfs.db.models.notification.NotificationChannel import NotificationChannel -from lcfs.db.models.notification.NotificationType import NotificationType - -logger = structlog.get_logger(__name__) - - -async def seed_notification_channels(session): - """ - Seeds the notification_channel table with predefined values if they do not already exist. - - Args: - session: The database session for committing the new records. - """ - channels_to_seed = [ - {"channel_name": "EMAIL", "enabled": True, "subscribe_by_default": True}, - {"channel_name": "IN_APP", "enabled": True, "subscribe_by_default": False}, - ] - - try: - for channel_data in channels_to_seed: - # Check if the NotificationChannel already exists - exists = await session.execute( - select(NotificationChannel).where( - NotificationChannel.channel_name == channel_data["channel_name"] - ) - ) - if not exists.scalars().first(): - channel = NotificationChannel(**channel_data) - session.add(channel) - except IntegrityError as ie: - logger.warning( - "Integrity error while seeding notification_channel", - error=str(ie), - exc_info=ie, - ) - except Exception as e: - context = { - "function": "seed_notification_channels", - } - logger.error( - "Error occurred while seeding notification_channel", - error=str(e), - exc_info=e, - **context, - ) - raise - - -async def seed_notification_types(session): - """ - Seeds the notification_type table with predefined values if they do not already exist. - - Args: - session: The database session for committing the new records. - """ - types_to_seed = [ - { - "name": "BCEID__COMPLIANCE_REPORT__DIRECTOR_ASSESSMENT", - "description": "Director assessed a compliance report or supplemental report.", - "email_content": "Email content", - "create_user": "system", - "update_user": "system", - }, - { - "name": "BCEID__INITIATIVE_AGREEMENT__DIRECTOR_APPROVAL", - "description": "Director approved the initiative agreement or transaction", - "email_content": "Email content", - "create_user": "system", - "update_user": "system", - }, - { - "name": "BCEID__TRANSFER__DIRECTOR_DECISION", - "description": "Director recorded or refused a transfer request", - "email_content": "Email content", - "create_user": "system", - "update_user": "system", - }, - { - "name": "BCEID__TRANSFER__PARTNER_ACTIONS", - "description": "A transfer partner took action (proposed, declined, rescinded, or signed & submitted) on a transfer request", - "email_content": "Email content", - "create_user": "system", - "update_user": "system", - }, - { - "name": "IDIR_ANALYST__COMPLIANCE_REPORT__DIRECTOR_DECISION", - "description": "Director assessed compliance report", - "email_content": "Email content", - "create_user": "system", - "update_user": "system", - }, - { - "name": "IDIR_ANALYST__COMPLIANCE_REPORT__MANAGER_RECOMMENDATION", - "description": "Compliance manager recommended action on the compliance report.", - "email_content": "Email content", - "create_user": "system", - "update_user": "system", - }, - { - "name": "IDIR_ANALYST__COMPLIANCE_REPORT__SUBMITTED_FOR_REVIEW", - "description": "Compliance report submitted for government analyst review or returned by compliance manager", - "email_content": "Email content", - "create_user": "system", - "update_user": "system", - }, - { - "name": "IDIR_ANALYST__INITIATIVE_AGREEMENT__RETURNED_TO_ANALYST", - "description": "Director approved/returned the initiative agreement to the analyst", - "email_content": "Email content", - "create_user": "system", - "update_user": "system", - }, - { - "name": "IDIR_ANALYST__TRANSFER__DIRECTOR_RECORDED", - "description": "Director recorded or refused a transfer request", - "email_content": "Email content", - "create_user": "system", - "update_user": "system", - }, - { - "name": "IDIR_ANALYST__TRANSFER__RESCINDED_ACTION", - "description": "A transfer request was rescinded by a transfer partner", - "email_content": "Email content", - "create_user": "system", - "update_user": "system", - }, - { - "name": "IDIR_ANALYST__TRANSFER__SUBMITTED_FOR_REVIEW", - "description": "Transfer request submitted for government analyst review", - "email_content": "Email content", - "create_user": "system", - "update_user": "system", - }, - { - "name": "IDIR_COMPLIANCE_MANAGER__COMPLIANCE_REPORT__ANALYST_RECOMMENDATION", - "description": "Analyst recommendation on the compliance report or returned by the director", - "email_content": "Email content", - "create_user": "system", - "update_user": "system", - }, - { - "name": "IDIR_COMPLIANCE_MANAGER__COMPLIANCE_REPORT__DIRECTOR_ASSESSMENT", - "description": "Director assessed a compliance report", - "email_content": "Email content", - "create_user": "system", - "update_user": "system", - }, - { - "name": "IDIR_COMPLIANCE_MANAGER__COMPLIANCE_REPORT__SUBMITTED_FOR_REVIEW", - "description": "Compliance report submitted for government analyst review", - "email_content": "Email content", - "create_user": "system", - "update_user": "system", - }, - { - "name": "IDIR_DIRECTOR__COMPLIANCE_REPORT__MANAGER_RECOMMENDATION", - "description": "Compliance manager recommended action on the compliance report", - "email_content": "Email content", - "create_user": "system", - "update_user": "system", - }, - { - "name": "IDIR_DIRECTOR__INITIATIVE_AGREEMENT__ANALYST_RECOMMENDATION", - "description": "Analyst recommendation provided for the initiative agreement", - "email_content": "Email content", - "create_user": "system", - "update_user": "system", - }, - { - "name": "IDIR_DIRECTOR__TRANSFER__ANALYST_RECOMMENDATION", - "description": "Analyst recommendation provided for the transfer request", - "email_content": "Email content", - "create_user": "system", - "update_user": "system", - }, - ] - - try: - for notification_type_data in types_to_seed: - # Check if the NotificationType already exists - exists = await session.execute( - select(NotificationType).where( - NotificationType.name == notification_type_data["name"] - ) - ) - if not exists.scalars().first(): - notification_type = NotificationType(**notification_type_data) - session.add(notification_type) - except IntegrityError as ie: - logger.warning( - "Integrity error while seeding notification_type", - error=str(ie), - exc_info=ie, - ) - except Exception as e: - context = { - "function": "seed_notification_types", - } - logger.error( - "Error occurred while seeding notification_type", - error=str(e), - exc_info=e, - **context, - ) - raise diff --git a/backend/lcfs/db/seeders/common/organization_status_seeder.py b/backend/lcfs/db/seeders/common/organization_status_seeder.py deleted file mode 100644 index e56e03504..000000000 --- a/backend/lcfs/db/seeders/common/organization_status_seeder.py +++ /dev/null @@ -1,64 +0,0 @@ -import structlog -from sqlalchemy import select -from lcfs.db.models.organization.OrganizationStatus import ( - OrganizationStatus, - OrgStatusEnum, -) - -logger = structlog.get_logger(__name__) - - -async def seed_organization_statuses(session): - """ - Seeds the organization statuses into the database, if they do not already exist. - - Args: - session: The database session for committing the new records. - """ - - org_statuses_to_seed = [ - { - "organization_status_id": 1, - "status": OrgStatusEnum.Unregistered, - "description": "Unregistered", - }, - { - "organization_status_id": 2, - "status": OrgStatusEnum.Registered, - "description": "Registered", - }, - { - "organization_status_id": 3, - "status": OrgStatusEnum.Suspended, - "description": "Suspended", - }, - { - "organization_status_id": 4, - "status": OrgStatusEnum.Canceled, - "description": "Canceled", - }, - ] - - try: - for org_status_data in org_statuses_to_seed: - # Check if the OrganizationStatus already exists based on status - exists = await session.execute( - select(OrganizationStatus).where( - OrganizationStatus.status == org_status_data["status"] - ) - ) - if not exists.scalars().first(): - org_status = OrganizationStatus(**org_status_data) - session.add(org_status) - - except Exception as e: - context = { - "function": "seed_organization_statuses", - } - logger.error( - "Error occurred while seeding organization statuses", - error=str(e), - exc_info=e, - **context, - ) - raise diff --git a/backend/lcfs/db/seeders/common/organization_type_seeder.py b/backend/lcfs/db/seeders/common/organization_type_seeder.py deleted file mode 100644 index d4d8e78a5..000000000 --- a/backend/lcfs/db/seeders/common/organization_type_seeder.py +++ /dev/null @@ -1,61 +0,0 @@ -import structlog -from sqlalchemy import select -from lcfs.db.models.organization.OrganizationType import OrganizationType, OrgTypeEnum - -logger = structlog.get_logger(__name__) - - -async def seed_organization_types(session): - """ - Seeds the organization types into the database, if they do not already exist. - - Args: - session: The database session for committing the new records. - """ - - org_types_to_seed = [ - { - "organization_type_id": 1, - "org_type": OrgTypeEnum.fuel_supplier, - "description": "Fuel Supplier", - }, - { - "organization_type_id": 2, - "org_type": OrgTypeEnum.electricity_supplier, - "description": "Electricity Supplier", - }, - { - "organization_type_id": 3, - "org_type": OrgTypeEnum.broker, - "description": "Broker", - }, - { - "organization_type_id": 4, - "org_type": OrgTypeEnum.utilities, - "description": "Utilities (local or public)", - }, - ] - - try: - for org_type_data in org_types_to_seed: - # Check if the OrganizationType already exists based on org_type - exists = await session.execute( - select(OrganizationType).where( - OrganizationType.org_type == org_type_data["org_type"] - ) - ) - if not exists.scalars().first(): - org_type = OrganizationType(**org_type_data) - session.add(org_type) - - except Exception as e: - context = { - "function": "seed_organization_types", - } - logger.error( - "Error occurred while seeding organization types", - error=str(e), - exc_info=e, - **context, - ) - raise diff --git a/backend/lcfs/db/seeders/common/role_seeder.py b/backend/lcfs/db/seeders/common/role_seeder.py deleted file mode 100644 index 4afc8ca3c..000000000 --- a/backend/lcfs/db/seeders/common/role_seeder.py +++ /dev/null @@ -1,116 +0,0 @@ -import structlog -from sqlalchemy import select -from lcfs.db.models.user.Role import Role, RoleEnum - -logger = structlog.get_logger(__name__) - - -async def seed_roles(session): - """ - Seeds the roles into the database, if they do not already exist. - - Args: - session: The database session for committing the new records. - """ - - roles_to_seed = [ - { - "role_id": 1, - "name": RoleEnum.GOVERNMENT, - "description": "Identifies a government user in the system.", - "is_government_role": True, - "display_order": 1, - }, - { - "role_id": 2, - "name": RoleEnum.SUPPLIER, - "description": "Identifies a supplier user in the system.", - "is_government_role": False, - "display_order": 2, - }, - { - "role_id": 3, - "name": RoleEnum.ADMINISTRATOR, - "description": "Can add/edit IDIR users and assign roles, add/edit organizations, BCeID users, and assign roles", - "is_government_role": True, - "display_order": 3, - }, - { - "role_id": 4, - "name": RoleEnum.ANALYST, - "description": "Can make recommendations on transfers, transactions, and compliance reports, manage file submissions, and add/edit fuel codes", - "is_government_role": True, - "display_order": 4, - }, - { - "role_id": 5, - "name": RoleEnum.COMPLIANCE_MANAGER, - "description": "Can make recommendations on compliance reports", - "is_government_role": True, - "display_order": 5, - }, - { - "role_id": 6, - "name": RoleEnum.DIRECTOR, - "description": "Can assess compliance reports and approve transactions", - "is_government_role": True, - "display_order": 6, - }, - { - "role_id": 7, - "name": RoleEnum.MANAGE_USERS, - "description": "Can add/edit BCeID users and assign roles", - "is_government_role": False, - "display_order": 7, - }, - { - "role_id": 8, - "name": RoleEnum.TRANSFER, - "description": "Can create/save transfers and submit files", - "is_government_role": False, - "display_order": 8, - }, - { - "role_id": 9, - "name": RoleEnum.COMPLIANCE_REPORTING, - "description": "Can create/save compliance reports and submit files", - "is_government_role": False, - "display_order": 9, - }, - { - "role_id": 10, - "name": RoleEnum.SIGNING_AUTHORITY, - "description": "Can sign and submit compliance reports to government and transfers to trade partners/government", - "is_government_role": False, - "display_order": 10, - }, - { - "role_id": 11, - "name": RoleEnum.READ_ONLY, - "description": "Can view transactions, compliance reports, and files", - "is_government_role": False, - "display_order": 11, - }, - ] - - try: - for role_data in roles_to_seed: - # Check if the Role already exists based on the name - exists = await session.execute( - select(Role).where(Role.name == role_data["name"]) - ) - if not exists.scalars().first(): - role = Role(**role_data) - session.add(role) - - except Exception as e: - context = { - "function": "seed_roles", - } - logger.error( - "Error occurred while seeding roles", - error=str(e), - exc_info=e, - **context, - ) - raise diff --git a/backend/lcfs/db/seeders/common/seed_fuel_data.json b/backend/lcfs/db/seeders/common/seed_fuel_data.json deleted file mode 100644 index 57b1178c4..000000000 --- a/backend/lcfs/db/seeders/common/seed_fuel_data.json +++ /dev/null @@ -1,1098 +0,0 @@ -{ - "provision_acts": [ - { - "provision_of_the_act_id": 1, - "name": "Prescribed carbon intensity - section 19 (a)", - "description": "Prescribed carbon intensity - section 19 (a)", - "effective_status": true - }, - { - "provision_of_the_act_id": 2, - "name": "Fuel code - section 19 (b) (i)", - "description": "Fuel code - section 19 (b) (i)", - "effective_status": true - }, - { - "provision_of_the_act_id": 3, - "name": "Default carbon intensity - section 19 (b) (ii)", - "description": "Default carbon intensity - section 19 (b) (ii)", - "effective_status": true - } - ], - "fuel_types": [ - { - "fuel_type_id": 1, - "fuel_type": "Biodiesel", - "fossil_derived": false, - "other_uses_fossil_derived": false, - "provision_1_id": 2, - "provision_2_id": 3, - "default_carbon_intensity": 100.21, - "units": "L", - "unrecognized": false - }, - { - "fuel_type_id": 2, - "fuel_type": "CNG", - "fossil_derived": false, - "other_uses_fossil_derived": true, - "provision_1_id": 2, - "provision_2_id": 3, - "default_carbon_intensity": 63.91, - "units": "m³", - "unrecognized": false - }, - { - "fuel_type_id": 3, - "fuel_type": "Electricity", - "fossil_derived": false, - "other_uses_fossil_derived": true, - "provision_1_id": 2, - "provision_2_id": 3, - "default_carbon_intensity": 12.14, - "units": "kWh", - "unrecognized": false - }, - { - "fuel_type_id": 4, - "fuel_type": "Ethanol", - "fossil_derived": false, - "other_uses_fossil_derived": false, - "provision_1_id": 2, - "provision_2_id": 3, - "default_carbon_intensity": 93.67, - "units": "L", - "unrecognized": false - }, - { - "fuel_type_id": 5, - "fuel_type": "HDRD", - "fossil_derived": false, - "other_uses_fossil_derived": false, - "provision_1_id": 2, - "provision_2_id": 3, - "default_carbon_intensity": 100.21, - "units": "L", - "unrecognized": false - }, - { - "fuel_type_id": 6, - "fuel_type": "Hydrogen", - "fossil_derived": false, - "other_uses_fossil_derived": true, - "provision_1_id": 2, - "provision_2_id": 3, - "default_carbon_intensity": 123.96, - "units": "kg", - "unrecognized": false - }, - { - "fuel_type_id": 7, - "fuel_type": "LNG", - "fossil_derived": false, - "other_uses_fossil_derived": true, - "provision_1_id": 2, - "provision_2_id": 3, - "default_carbon_intensity": 90.11, - "units": "kg", - "unrecognized": false - }, - { - "fuel_type_id": 11, - "fuel_type": "Alternative jet fuel", - "fossil_derived": false, - "other_uses_fossil_derived": false, - "provision_1_id": 2, - "provision_2_id": 3, - "default_carbon_intensity": 88.83, - "units": "L", - "unrecognized": false - }, - { - "fuel_type_id": 13, - "fuel_type": "Propane", - "fossil_derived": false, - "other_uses_fossil_derived": true, - "provision_1_id": 2, - "provision_2_id": 3, - "default_carbon_intensity": 79.87, - "units": "L", - "unrecognized": false - }, - { - "fuel_type_id": 14, - "fuel_type": "Renewable gasoline", - "fossil_derived": false, - "other_uses_fossil_derived": false, - "provision_1_id": 2, - "provision_2_id": 3, - "default_carbon_intensity": 93.67, - "units": "L", - "unrecognized": false - }, - { - "fuel_type_id": 15, - "fuel_type": "Renewable naphtha", - "fossil_derived": false, - "other_uses_fossil_derived": false, - "provision_1_id": 2, - "provision_2_id": 3, - "default_carbon_intensity": 93.67, - "units": "L", - "unrecognized": false - }, - { - "fuel_type_id": 16, - "fuel_type": "Fossil-derived diesel", - "fossil_derived": true, - "other_uses_fossil_derived": true, - "provision_1_id": 1, - "default_carbon_intensity": 94.38, - "units": "L", - "unrecognized": false - }, - { - "fuel_type_id": 17, - "fuel_type": "Fossil-derived gasoline", - "fossil_derived": true, - "other_uses_fossil_derived": true, - "provision_1_id": 1, - "default_carbon_intensity": 93.67, - "units": "L", - "unrecognized": false - }, - { - "fuel_type_id": 18, - "fuel_type": "Fossil-derived jet fuel", - "fossil_derived": true, - "other_uses_fossil_derived": true, - "provision_1_id": 1, - "default_carbon_intensity": 88.83, - "units": "L", - "unrecognized": false - }, - { - "fuel_type_id": 19, - "fuel_type": "Other", - "fossil_derived": false, - "other_uses_fossil_derived": false, - "provision_1_id": 2, - "provision_2_id": 3, - "default_carbon_intensity": 0, - "units": "L", - "unrecognized": true - }, - { - "fuel_type_id": 20, - "fuel_type": "Other diesel", - "fossil_derived": false, - "other_uses_fossil_derived": false, - "provision_1_id": 1, - "default_carbon_intensity": 100.21, - "units": "L", - "unrecognized": false - } - ], - "fuel_code_prefixes": [ - { - "fuel_code_prefix_id": 1, - "prefix": "BCLCF" - }, - { - "fuel_code_prefix_id": 2, - "prefix": "PROXY" - } - ], - "fuel_code_statuses": [ - { - "fuel_code_status_id": 1, - "status": "Draft", - "description": "Initial state of the fuel code", - "display_order": 1 - }, - { - "fuel_code_status_id": 2, - "status": "Approved", - "description": "Fuel code has been approved", - "display_order": 2 - }, - { - "fuel_code_status_id": 3, - "status": "Deleted", - "description": "Fuel code has been deleted", - "display_order": 3 - } - ], - "transport_modes": [ - { - "transport_mode_id": 1, - "transport_mode": "Truck" - }, - { - "transport_mode_id": 2, - "transport_mode": "Rail" - }, - { - "transport_mode_id": 3, - "transport_mode": "Marine-domestic" - }, - { - "transport_mode_id": 4, - "transport_mode": "Adjacent" - }, - { - "transport_mode_id": 5, - "transport_mode": "Pipeline" - } - ], - "fuel_categories": [ - { - "fuel_category_id": 1, - "category": "Gasoline", - "description": "Gasoline", - "default_carbon_intensity": 93.67 - }, - { - "fuel_category_id": 2, - "category": "Diesel", - "description": "Diesel", - "default_carbon_intensity": 100.21 - }, - { - "fuel_category_id": 3, - "category": "Jet fuel", - "description": "Jet fuel", - "default_carbon_intensity": 88.83 - } - ], - "end_use_types": [ - { - "end_use_type_id": 1, - "type": "Light duty motor vehicles", - "intended_use": true - }, - { - "end_use_type_id": 2, - "type": "Other or unknown" - }, - { - "end_use_type_id": 3, - "type": "Fuel cell vehicle" - }, - { - "end_use_type_id": 4, - "type": "Battery bus", - "intended_use": true - }, - { - "end_use_type_id": 5, - "type": "Battery truck", - "intended_use": true - }, - { - "end_use_type_id": 6, - "type": "Cargo handling equipment", - "intended_use": true - }, - { - "end_use_type_id": 7, - "type": "Fixed guiderail", - "intended_use": true - }, - { - "end_use_type_id": 8, - "type": "Ground support equipment", - "intended_use": true - }, - { - "end_use_type_id": 9, - "type": "Heavy forklift", - "intended_use": true - }, - { - "end_use_type_id": 10, - "type": "Shore power", - "intended_use": true - }, - { - "end_use_type_id": 11, - "type": "Trolley bus", - "intended_use": true - }, - { - "end_use_type_id": 12, - "type": "Compression-ignition engine" - }, - { - "end_use_type_id": 13, - "type": "Other", - "intended_use": true - }, - { - "end_use_type_id": 14, - "type": "Aircraft", - "intended_use": true - }, - { - "end_use_type_id": 15, - "type": "Compression-ignition engine- Marine, general", - "intended_use": true - }, - { - "end_use_type_id": 16, - "type": "Compression-ignition engine- Marine, operated within 51 to 75% of load range", - "intended_use": true - }, - { - "end_use_type_id": 17, - "type": "Compression-ignition engine- Marine, operated within 76 to 100% of load range", - "intended_use": true - }, - { - "end_use_type_id": 18, - "type": "Compression-ignition engine- Marine, with methane slip reduction kit- General", - "intended_use": true - }, - { - "end_use_type_id": 19, - "type": "Compression-ignition engine- Marine, with methane slip reduction kit- Operated within 26 to 75% of load range", - "intended_use": true - }, - { - "end_use_type_id": 20, - "type": "Compression-ignition engine- Marine, with methane slip reduction kit- Operated within 76 to 100% of load range", - "intended_use": true - }, - { - "end_use_type_id": 21, - "type": "Compression-ignition engine- Marine, unknown whether kit is installed or average operating load range", - "intended_use": true - }, - { - "end_use_type_id": 22, - "type": "Unknown engine type", - "intended_use": true - }, - { - "end_use_type_id": 23, - "type": "Other (i.e. road transportation)", - "intended_use": true - } - ], - "unit_of_measures": [ - { - "uom_id": 1, - "name": "MJ/L", - "description": "Megajoules per litre" - }, - { - "uom_id": 2, - "name": "MJ/kWh", - "description": "Megajoules per kilowatt hour" - }, - { - "uom_id": 3, - "name": "MJ/m³", - "description": "Megajoules per cubic metre" - }, - { - "uom_id": 4, - "name": "MJ/kg", - "description": "Megajoules per kilogram" - }, - { - "uom_id": 5, - "name": "gCO²e/MJ", - "description": "grams of carbon dioxide equivalent per megajoule" - } - ], - "ucis": [ - { - "additional_uci_id": 1, - "fuel_type_id": 7, - "uom_id": 5, - "intensity": 0 - }, - { - "additional_uci_id": 2, - "uom_id": 5, - "intensity": 0 - }, - { - "additional_uci_id": 3, - "fuel_type_id": 7, - "uom_id": 5, - "end_use_type_id": 15, - "intensity": 27.3 - }, - { - "additional_uci_id": 4, - "fuel_type_id": 7, - "uom_id": 5, - "end_use_type_id": 16, - "intensity": 17.8 - }, - { - "additional_uci_id": 5, - "fuel_type_id": 7, - "uom_id": 5, - "end_use_type_id": 17, - "intensity": 12.2 - }, - { - "additional_uci_id": 6, - "fuel_type_id": 7, - "uom_id": 5, - "end_use_type_id": 18, - "intensity": 10.6 - }, - { - "additional_uci_id": 7, - "fuel_type_id": 7, - "uom_id": 5, - "end_use_type_id": 19, - "intensity": 8.4 - }, - { - "additional_uci_id": 8, - "fuel_type_id": 7, - "uom_id": 5, - "end_use_type_id": 20, - "intensity": 8.0 - }, - { - "additional_uci_id": 9, - "fuel_type_id": 7, - "uom_id": 5, - "end_use_type_id": 21, - "intensity": 27.3 - }, - { - "additional_uci_id": 10, - "fuel_type_id": 7, - "uom_id": 5, - "end_use_type_id": 22, - "intensity": 27.3 - }, - { - "additional_uci_id": 11, - "fuel_type_id": 7, - "uom_id": 5, - "end_use_type_id": 23, - "intensity": 0 - } - ], - "eers": [ - { - "eer_id": 1, - "fuel_category_id": 1, - "fuel_type_id": 2, - "ratio": 0.9 - }, - { - "eer_id": 2, - "fuel_category_id": 1, - "fuel_type_id": 3, - "end_use_type_id": 1, - "ratio": 3.5 - }, - { - "eer_id": 3, - "fuel_category_id": 1, - "fuel_type_id": 3, - "end_use_type_id": 2, - "ratio": 1.0 - }, - { - "eer_id": 4, - "fuel_category_id": 1, - "fuel_type_id": 6, - "end_use_type_id": 3, - "ratio": 2.4 - }, - { - "eer_id": 5, - "fuel_category_id": 1, - "fuel_type_id": 6, - "end_use_type_id": 2, - "ratio": 0.9 - }, - { - "eer_id": 6, - "fuel_category_id": 1, - "fuel_type_id": 13, - "ratio": 0.9 - }, - { - "eer_id": 7, - "fuel_category_id": 2, - "fuel_type_id": 2, - "ratio": 0.9 - }, - { - "eer_id": 8, - "fuel_category_id": 2, - "fuel_type_id": 3, - "end_use_type_id": 4, - "ratio": 3.8 - }, - { - "eer_id": 9, - "fuel_category_id": 2, - "fuel_type_id": 3, - "end_use_type_id": 5, - "ratio": 3.2 - }, - { - "eer_id": 10, - "fuel_category_id": 2, - "fuel_type_id": 3, - "end_use_type_id": 6, - "ratio": 2.5 - }, - { - "eer_id": 11, - "fuel_category_id": 2, - "fuel_type_id": 3, - "end_use_type_id": 7, - "ratio": 2.9 - }, - { - "eer_id": 12, - "fuel_category_id": 2, - "fuel_type_id": 3, - "end_use_type_id": 8, - "ratio": 2.5 - }, - { - "eer_id": 13, - "fuel_category_id": 2, - "fuel_type_id": 3, - "end_use_type_id": 9, - "ratio": 3.9 - }, - { - "eer_id": 14, - "fuel_category_id": 2, - "fuel_type_id": 3, - "end_use_type_id": 10, - "ratio": 2.8 - }, - { - "eer_id": 15, - "fuel_category_id": 2, - "fuel_type_id": 3, - "end_use_type_id": 11, - "ratio": 2.4 - }, - { - "eer_id": 16, - "fuel_category_id": 2, - "fuel_type_id": 3, - "end_use_type_id": 2, - "ratio": 1.0 - }, - { - "eer_id": 17, - "fuel_category_id": 2, - "fuel_type_id": 6, - "end_use_type_id": 3, - "ratio": 1.8 - }, - { - "eer_id": 18, - "fuel_category_id": 2, - "fuel_type_id": 6, - "end_use_type_id": 2, - "ratio": 0.9 - }, - { - "eer_id": 19, - "fuel_category_id": 2, - "fuel_type_id": 13, - "ratio": 0.9 - }, - { - "eer_id": 20, - "fuel_category_id": 3, - "fuel_type_id": 3, - "ratio": 2.5 - }, - { - "eer_id": 21, - "fuel_category_id": 3, - "fuel_type_id": 11, - "ratio": 1.0 - }, - { - "eer_id": 22, - "fuel_category_id": 2, - "fuel_type_id": 7, - "end_use_type_id": 15, - "ratio": 1.0 - }, - { - "eer_id": 23, - "fuel_category_id": 2, - "fuel_type_id": 7, - "end_use_type_id": 16, - "ratio": 1.0 - }, - { - "eer_id": 24, - "fuel_category_id": 2, - "fuel_type_id": 7, - "end_use_type_id": 17, - "ratio": 1.0 - }, - { - "eer_id": 25, - "fuel_category_id": 2, - "fuel_type_id": 7, - "end_use_type_id": 18, - "ratio": 1.0 - }, - { - "eer_id": 26, - "fuel_category_id": 2, - "fuel_type_id": 7, - "end_use_type_id": 19, - "ratio": 1.0 - }, - { - "eer_id": 27, - "fuel_category_id": 2, - "fuel_type_id": 7, - "end_use_type_id": 20, - "ratio": 1.0 - }, - { - "eer_id": 28, - "fuel_category_id": 2, - "fuel_type_id": 7, - "end_use_type_id": 21, - "ratio": 1.0 - }, - { - "eer_id": 29, - "fuel_category_id": 2, - "fuel_type_id": 7, - "end_use_type_id": 22, - "ratio": 0.9 - }, - { - "eer_id": 30, - "fuel_category_id": 2, - "fuel_type_id": 7, - "end_use_type_id": 23, - "ratio": 0.9 - } - ], - "energy_densities": [ - { - "energy_density_id": 1, - "fuel_type_id": 17, - "uom_id": 1, - "density": 34.69 - }, - { - "energy_density_id": 2, - "fuel_type_id": 4, - "uom_id": 1, - "density": 23.58 - }, - { - "energy_density_id": 3, - "fuel_type_id": 14, - "uom_id": 1, - "density": 34.69 - }, - { - "energy_density_id": 4, - "fuel_type_id": 15, - "uom_id": 1, - "density": 34.51 - }, - { - "energy_density_id": 5, - "fuel_type_id": 16, - "uom_id": 1, - "density": 38.65 - }, - { - "energy_density_id": 6, - "fuel_type_id": 1, - "uom_id": 1, - "density": 35.40 - }, - { - "energy_density_id": 7, - "fuel_type_id": 5, - "uom_id": 1, - "density": 37.89 - }, - { - "energy_density_id": 9, - "fuel_type_id": 18, - "uom_id": 1, - "density": 37.40 - }, - { - "energy_density_id": 10, - "fuel_type_id": 11, - "uom_id": 1, - "density": 36.00 - }, - { - "energy_density_id": 11, - "fuel_type_id": 3, - "uom_id": 2, - "density": 3.60 - }, - { - "energy_density_id": 12, - "fuel_type_id": 6, - "uom_id": 2, - "density": 141.76 - }, - { - "energy_density_id": 13, - "fuel_type_id": 13, - "uom_id": 1, - "density": 25.62 - }, - { - "energy_density_id": 14, - "fuel_type_id": 2, - "uom_id": 3, - "density": 38.27 - }, - { - "energy_density_id": 15, - "fuel_type_id": 7, - "uom_id": 4, - "density": 53.54 - }, - { - "energy_density_id": 16, - "fuel_type_id": 20, - "uom_id": 1, - "density": 36.51 - } - ], - "target_carbon_intensities": [ - { - "target_carbon_intensity_id": 1, - "compliance_period_id": 15, - "fuel_category_id": 1, - "target_carbon_intensity": 78.68, - "reduction_target_percentage": 16.0 - }, - { - "target_carbon_intensity_id": 2, - "compliance_period_id": 16, - "fuel_category_id": 1, - "target_carbon_intensity": 76.53, - "reduction_target_percentage": 18.3 - }, - { - "target_carbon_intensity_id": 3, - "compliance_period_id": 17, - "fuel_category_id": 1, - "target_carbon_intensity": 74.37, - "reduction_target_percentage": 20.6 - }, - { - "target_carbon_intensity_id": 4, - "compliance_period_id": 18, - "fuel_category_id": 1, - "target_carbon_intensity": 72.13, - "reduction_target_percentage": 23.0 - }, - { - "target_carbon_intensity_id": 5, - "compliance_period_id": 19, - "fuel_category_id": 1, - "target_carbon_intensity": 69.97, - "reduction_target_percentage": 25.3 - }, - { - "target_carbon_intensity_id": 6, - "compliance_period_id": 20, - "fuel_category_id": 1, - "target_carbon_intensity": 67.72, - "reduction_target_percentage": 27.7 - }, - { - "target_carbon_intensity_id": 7, - "compliance_period_id": 21, - "fuel_category_id": 1, - "target_carbon_intensity": 65.57, - "reduction_target_percentage": 30.0 - }, - { - "target_carbon_intensity_id": 8, - "compliance_period_id": 15, - "fuel_category_id": 2, - "target_carbon_intensity": 79.28, - "reduction_target_percentage": 16.0 - }, - { - "target_carbon_intensity_id": 9, - "compliance_period_id": 16, - "fuel_category_id": 2, - "target_carbon_intensity": 77.11, - "reduction_target_percentage": 18.3 - }, - { - "target_carbon_intensity_id": 10, - "compliance_period_id": 17, - "fuel_category_id": 2, - "target_carbon_intensity": 74.94, - "reduction_target_percentage": 20.6 - }, - { - "target_carbon_intensity_id": 11, - "compliance_period_id": 18, - "fuel_category_id": 2, - "target_carbon_intensity": 72.67, - "reduction_target_percentage": 23.0 - }, - { - "target_carbon_intensity_id": 12, - "compliance_period_id": 19, - "fuel_category_id": 2, - "target_carbon_intensity": 70.50, - "reduction_target_percentage": 25.3 - }, - { - "target_carbon_intensity_id": 13, - "compliance_period_id": 20, - "fuel_category_id": 2, - "target_carbon_intensity": 68.24, - "reduction_target_percentage": 27.7 - }, - { - "target_carbon_intensity_id": 14, - "compliance_period_id": 21, - "fuel_category_id": 2, - "target_carbon_intensity": 66.07, - "reduction_target_percentage": 30.0 - }, - { - "target_carbon_intensity_id": 15, - "compliance_period_id": 15, - "fuel_category_id": 3, - "target_carbon_intensity": 88.83, - "reduction_target_percentage": 0.0 - }, - { - "target_carbon_intensity_id": 16, - "compliance_period_id": 16, - "fuel_category_id": 3, - "target_carbon_intensity": 88.83, - "reduction_target_percentage": 0.0 - }, - { - "target_carbon_intensity_id": 17, - "compliance_period_id": 17, - "fuel_category_id": 3, - "target_carbon_intensity": 87.05, - "reduction_target_percentage": 2.0 - }, - { - "target_carbon_intensity_id": 18, - "compliance_period_id": 18, - "fuel_category_id": 3, - "target_carbon_intensity": 85.28, - "reduction_target_percentage": 4.0 - }, - { - "target_carbon_intensity_id": 19, - "compliance_period_id": 19, - "fuel_category_id": 3, - "target_carbon_intensity": 83.50, - "reduction_target_percentage": 6.0 - }, - { - "target_carbon_intensity_id": 20, - "compliance_period_id": 20, - "fuel_category_id": 3, - "target_carbon_intensity": 81.72, - "reduction_target_percentage": 8.0 - }, - { - "target_carbon_intensity_id": 21, - "compliance_period_id": 21, - "fuel_category_id": 3, - "target_carbon_intensity": 79.95, - "reduction_target_percentage": 10.0 - } - ], - "fuel_instances": [ - { - "fuel_instance_id": 1, - "fuel_type_id": 1, - "fuel_category_id": 2 - }, - { - "fuel_instance_id": 2, - "fuel_type_id": 2, - "fuel_category_id": 1 - }, - { - "fuel_instance_id": 3, - "fuel_type_id": 2, - "fuel_category_id": 2 - }, - { - "fuel_instance_id": 4, - "fuel_type_id": 3, - "fuel_category_id": 1 - }, - { - "fuel_instance_id": 5, - "fuel_type_id": 3, - "fuel_category_id": 2 - }, - { - "fuel_instance_id": 6, - "fuel_type_id": 3, - "fuel_category_id": 3 - }, - { - "fuel_instance_id": 7, - "fuel_type_id": 4, - "fuel_category_id": 1 - }, - { - "fuel_instance_id": 8, - "fuel_type_id": 5, - "fuel_category_id": 2 - }, - { - "fuel_instance_id": 9, - "fuel_type_id": 6, - "fuel_category_id": 1 - }, - { - "fuel_instance_id": 10, - "fuel_type_id": 6, - "fuel_category_id": 2 - }, - { - "fuel_instance_id": 11, - "fuel_type_id": 6, - "fuel_category_id": 3 - }, - { - "fuel_instance_id": 12, - "fuel_type_id": 7, - "fuel_category_id": 2 - }, - { - "fuel_instance_id": 16, - "fuel_type_id": 11, - "fuel_category_id": 3 - }, - { - "fuel_instance_id": 18, - "fuel_type_id": 13, - "fuel_category_id": 1 - }, - { - "fuel_instance_id": 19, - "fuel_type_id": 13, - "fuel_category_id": 2 - }, - { - "fuel_instance_id": 20, - "fuel_type_id": 14, - "fuel_category_id": 1 - }, - { - "fuel_instance_id": 21, - "fuel_type_id": 15, - "fuel_category_id": 1 - }, - { - "fuel_instance_id": 22, - "fuel_type_id": 16, - "fuel_category_id": 2 - }, - { - "fuel_instance_id": 23, - "fuel_type_id": 17, - "fuel_category_id": 1 - }, - { - "fuel_instance_id": 24, - "fuel_type_id": 18, - "fuel_category_id": 3 - }, - { - "fuel_instance_id": 25, - "fuel_type_id": 19, - "fuel_category_id": 1 - }, - { - "fuel_instance_id": 26, - "fuel_type_id": 19, - "fuel_category_id": 2 - }, - { - "fuel_instance_id": 27, - "fuel_type_id": 19, - "fuel_category_id": 3 - }, - { - "fuel_instance_id": 28, - "fuel_type_id": 20, - "fuel_category_id": 2 - } - ], - "levels_of_equipment": [ - { - "level_of_equipment_id": 1, - "name": "Level 3 - Direct current fast charging", - "display_order": 1 - }, - { - "level_of_equipment_id": 2, - "name": "Level 2 - High voltage, operating above level 1", - "display_order": 2 - }, - { - "level_of_equipment_id": 3, - "name": "Level 1 - Low voltage, operating at 120V AC or less", - "display_order": 3 - }, - { - "level_of_equipment_id": 4, - "name": "Other - Additional information provided in notes field", - "display_order": 4 - } - ], - "fuel_measurement_types": [ - { - "fuel_measurement_type_id": 1, - "type": "Separate utility meter", - "display_order": 1 - }, - { - "fuel_measurement_type_id": 2, - "type": "Equipment meter (remote access)", - "display_order": 2 - }, - { - "fuel_measurement_type_id": 3, - "type": "Equipment meter (physical access)", - "display_order": 3 - }, - { - "fuel_measurement_type_id": 4, - "type": "No meter or estimated", - "display_order": 4 - } - ] -} \ No newline at end of file diff --git a/backend/lcfs/db/seeders/common/transfer_categories_seeder.py b/backend/lcfs/db/seeders/common/transfer_categories_seeder.py deleted file mode 100644 index 29d432243..000000000 --- a/backend/lcfs/db/seeders/common/transfer_categories_seeder.py +++ /dev/null @@ -1,49 +0,0 @@ -import structlog -from sqlalchemy import select -from sqlalchemy.exc import IntegrityError -from sqlalchemy.ext.asyncio import AsyncSession -from lcfs.db.models.transfer.TransferCategory import ( - TransferCategory, - TransferCategoryEnum, -) - -logger = structlog.get_logger(__name__) - - -async def seed_transfer_categories(session: AsyncSession): - """ - Seeds the transfer categories into the database, if they do not already exist. - - Args: - session: The database session for committing the new records. - """ - category_data = [ - {"transfer_category_id": 1, "category": TransferCategoryEnum.A}, - {"transfer_category_id": 2, "category": TransferCategoryEnum.B}, - {"transfer_category_id": 3, "category": TransferCategoryEnum.C}, - {"transfer_category_id": 4, "category": TransferCategoryEnum.D}, - ] - - try: - for data in category_data: - # Check if the Category already exists based on category - exists = await session.execute( - select(TransferCategory).where( - TransferCategory.category == data["category"] - ) - ) - if not exists.scalars().first(): - new_category = TransferCategory(**data) - session.add(new_category) - - except Exception as e: - context = { - "function": "seed_transfer_categories", - } - logger.error( - "Error occurred while seeding transfer categories", - error=str(e), - exc_info=e, - **context, - ) - raise diff --git a/backend/lcfs/db/seeders/common/transfer_status_seeder.py b/backend/lcfs/db/seeders/common/transfer_status_seeder.py deleted file mode 100644 index fcf2bc4e9..000000000 --- a/backend/lcfs/db/seeders/common/transfer_status_seeder.py +++ /dev/null @@ -1,104 +0,0 @@ -import structlog -from sqlalchemy import select -from lcfs.db.models.transfer.TransferStatus import TransferStatus, TransferStatusEnum - -logger = structlog.get_logger(__name__) - - -async def seed_transfer_statuses(session): - """ - Seeds the transfer statuses into the database, if they do not already exist. - - Args: - session: The database session for committing the new records. - """ - - transfer_statuses_to_seed = [ - { - "transfer_status_id": 1, - "status": TransferStatusEnum.Draft, - "visible_to_transferor": True, - "visible_to_transferee": False, - "visible_to_government": False, - }, - { - "transfer_status_id": 2, - "status": TransferStatusEnum.Deleted, - "visible_to_transferor": False, - "visible_to_transferee": False, - "visible_to_government": False, - }, - { - "transfer_status_id": 3, - "status": TransferStatusEnum.Sent, - "visible_to_transferor": True, - "visible_to_transferee": True, - "visible_to_government": False, - }, - { - "transfer_status_id": 4, - "status": TransferStatusEnum.Submitted, - "visible_to_transferor": True, - "visible_to_transferee": True, - "visible_to_government": True, - }, - { - "transfer_status_id": 5, - "status": TransferStatusEnum.Recommended, - "visible_to_transferor": True, - "visible_to_transferee": True, - "visible_to_government": True, - }, - { - "transfer_status_id": 6, - "status": TransferStatusEnum.Recorded, - "visible_to_transferor": True, - "visible_to_transferee": True, - "visible_to_government": True, - }, - { - "transfer_status_id": 7, - "status": TransferStatusEnum.Refused, - "visible_to_transferor": True, - "visible_to_transferee": True, - "visible_to_government": True, - }, - { - "transfer_status_id": 8, - "status": TransferStatusEnum.Declined, - "visible_to_transferor": True, - "visible_to_transferee": True, - "visible_to_government": False, - }, - { - "transfer_status_id": 9, - "status": TransferStatusEnum.Rescinded, - "visible_to_transferor": True, - "visible_to_transferee": True, - "visible_to_government": True, - }, - ] - - try: - for transfer_status_data in transfer_statuses_to_seed: - # Check if the TransferStatus already exists based on status - exists = await session.execute( - select(TransferStatus).where( - TransferStatus.status == transfer_status_data["status"] - ) - ) - if not exists.scalars().first(): - transfer_status = TransferStatus(**transfer_status_data) - session.add(transfer_status) - - except Exception as e: - context = { - "function": "seed_transfer_statuses", - } - logger.error( - "Error occurred while seeding transfer statuses", - error=str(e), - exc_info=e, - **context, - ) - raise diff --git a/backend/lcfs/db/seeders/common_seeder.py b/backend/lcfs/db/seeders/common_seeder.py deleted file mode 100644 index 55c898920..000000000 --- a/backend/lcfs/db/seeders/common_seeder.py +++ /dev/null @@ -1,102 +0,0 @@ -import structlog -import asyncio -from sqlalchemy.ext.asyncio import AsyncSession -from sqlalchemy import text - -from lcfs.db.seeders.common.compliance_period_seeder import seed_compliance_periods -from lcfs.db.seeders.common.organization_type_seeder import seed_organization_types -from lcfs.db.seeders.common.organization_status_seeder import seed_organization_statuses -from lcfs.db.seeders.common.role_seeder import seed_roles -from lcfs.db.seeders.common.transfer_status_seeder import seed_transfer_statuses -from lcfs.db.seeders.common.transfer_categories_seeder import seed_transfer_categories -from lcfs.db.seeders.common.admin_adjustment_status_seeder import ( - seed_admin_adjustment_statuses, -) -from lcfs.db.seeders.common.initiative_agreement_status_seeder import ( - seed_initiative_agreement_statuses, -) -from lcfs.db.seeders.common.fuel_data_seeder import seed_static_fuel_data -from lcfs.db.seeders.common.compliance_report_status_seeder import ( - seed_compliance_report_statuses, -) -from lcfs.db.seeders.common.allocation_agreement_seeder import ( - seed_allocation_transaction_types, -) -from lcfs.db.seeders.common.end_user_type_seeder import ( - seed_end_user_types, -) -from lcfs.db.seeders.common.notifications_seeder import ( - seed_notification_types, - seed_notification_channels, -) - -logger = structlog.get_logger(__name__) - - -async def update_sequences(session): - """ - Function to update sequences for all tables after seeding. - """ - sequences = { - "fuel_code": "fuel_code_id", - "transport_mode": "transport_mode_id", - "provision_of_the_act": "provision_of_the_act_id", - "fuel_type": "fuel_type_id", - "fuel_code_prefix": "fuel_code_prefix_id", - "fuel_code_status": "fuel_code_status_id", - "fuel_category": "fuel_category_id", - "end_use_type": "end_use_type_id", - "unit_of_measure": "uom_id", - "additional_carbon_intensity": "additional_uci_id", - "energy_effectiveness_ratio": "eer_id", - "energy_density": "energy_density_id", - "target_carbon_intensity": "target_carbon_intensity_id", - "compliance_report_status": "compliance_report_status_id", - "admin_adjustment_status": "admin_adjustment_status_id", - "compliance_period": "compliance_period_id", - "initiative_agreement_status": "initiative_agreement_status_id", - "organization_status": "organization_status_id", - "organization_type": "organization_type_id", - "transfer_category": "transfer_category_id", - "transfer_status": "transfer_status_id", - "role": "role_id", - "end_user_type": "end_user_type_id", - "notification_type": "notification_type_id", - "notification_channel": "notification_channel_id", - } - - for table, column in sequences.items(): - sequence_name = f"{table}_{column}_seq" - max_value_query = text( - f"SELECT setval('{sequence_name}', COALESCE((SELECT MAX({column}) + 1 FROM {table}), 1), false)" - ) - await session.execute(max_value_query) - - -async def seed_common(session: AsyncSession): - """ - Function to seed the database with common data. - """ - await seed_compliance_periods(session) - await seed_organization_types(session) - await seed_organization_statuses(session) - await seed_roles(session) - await seed_transfer_statuses(session) - await seed_transfer_categories(session) - await seed_admin_adjustment_statuses(session) - await seed_initiative_agreement_statuses(session) - await seed_static_fuel_data(session) - await seed_compliance_report_statuses(session) - await seed_allocation_transaction_types(session) - await seed_end_user_types(session) - await seed_notification_types(session) - await seed_notification_channels(session) - - # Update sequences after all seeders have run - await update_sequences(session) - - logger.info("Common database seeding completed successfully.") - - -if __name__ == "__main__": - asyncio.run(seed_common()) diff --git a/backend/lcfs/db/seeders/seed_database.py b/backend/lcfs/db/seeders/seed_database.py index c840d5cf6..f40bdb1b0 100644 --- a/backend/lcfs/db/seeders/seed_database.py +++ b/backend/lcfs/db/seeders/seed_database.py @@ -22,7 +22,6 @@ async def seed_database(environment): async with session.begin(): try: logger.info("Database seeding started.") - await seed_common(session) if environment == "dev": await seed_dev(session) From 725fff4de9e8aa119d92b0b5dd12f81d34b8482b Mon Sep 17 00:00:00 2001 From: Kevin Hashimoto Date: Mon, 30 Dec 2024 12:51:52 -0800 Subject: [PATCH 2/5] fix: remove wrong imports --- backend/lcfs/db/seeders/seed_database.py | 1 - 1 file changed, 1 deletion(-) diff --git a/backend/lcfs/db/seeders/seed_database.py b/backend/lcfs/db/seeders/seed_database.py index f40bdb1b0..d1c5e3a6c 100644 --- a/backend/lcfs/db/seeders/seed_database.py +++ b/backend/lcfs/db/seeders/seed_database.py @@ -5,7 +5,6 @@ from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession from sqlalchemy.orm import sessionmaker -from lcfs.db.seeders.common_seeder import seed_common from lcfs.db.seeders.dev_seeder import seed_dev from lcfs.db.seeders.prod_seeder import seed_prod from lcfs.db.seeders.test_seeder import seed_test From 90ad92cdcfd9896fcc43f0a2bf3d1609bdf678b6 Mon Sep 17 00:00:00 2001 From: Kevin Hashimoto Date: Mon, 30 Dec 2024 15:35:36 -0800 Subject: [PATCH 3/5] fix: dependencies --- .../versions/2024-12-24-07-40_d9cdd9fca0ce.py | 91 ++++++++++--------- 1 file changed, 50 insertions(+), 41 deletions(-) diff --git a/backend/lcfs/db/migrations/versions/2024-12-24-07-40_d9cdd9fca0ce.py b/backend/lcfs/db/migrations/versions/2024-12-24-07-40_d9cdd9fca0ce.py index e1a57b653..ea13eb70f 100644 --- a/backend/lcfs/db/migrations/versions/2024-12-24-07-40_d9cdd9fca0ce.py +++ b/backend/lcfs/db/migrations/versions/2024-12-24-07-40_d9cdd9fca0ce.py @@ -121,7 +121,7 @@ def upgrade() -> None: ON CONFLICT (initiative_agreement_status_id) DO NOTHING; """) - # 9. Static Fuel Data - Reordered for dependencies + # 9. Static Fuel Data # Unit of Measures first op.execute(""" INSERT INTO unit_of_measure (uom_id, name, description) @@ -165,36 +165,6 @@ def upgrade() -> None: """) - # Energy Effectiveness Ratios - op.execute(""" - INSERT INTO energy_effectiveness_ratio (eer_id, end_use_type_id, ratio, effective_status) - VALUES - (1, 1, 3.4, TRUE), - (2, 2, 1.0, TRUE), - (3, 3, 2.5, TRUE), - (4, 4, 4.4, TRUE), - (5, 5, 4.4, TRUE), - (6, 6, 2.7, TRUE), - (7, 7, 2.9, TRUE), - (8, 8, 2.7, TRUE), - (9, 9, 2.7, TRUE), - (10, 10, 2.7, TRUE), - (11, 11, 2.9, TRUE), - (12, 12, 1.0, TRUE), - (13, 13, 1.0, TRUE), - (14, 14, 1.0, TRUE), - (15, 15, 1.0, TRUE), - (16, 16, 1.0, TRUE), - (17, 17, 1.0, TRUE), - (18, 18, 1.0, TRUE), - (19, 19, 1.0, TRUE), - (20, 20, 1.0, TRUE), - (21, 21, 1.0, TRUE), - (22, 22, 1.0, TRUE), - (23, 23, 1.0, TRUE) - ON CONFLICT (eer_id) DO NOTHING; - """) - # Provision Acts op.execute(""" INSERT INTO provision_of_the_act (provision_of_the_act_id, name, description, effective_status) @@ -205,6 +175,16 @@ def upgrade() -> None: ON CONFLICT (provision_of_the_act_id) DO NOTHING; """) + # Fuel Categories + op.execute(""" + INSERT INTO fuel_category (fuel_category_id, category, description, default_carbon_intensity, effective_status) + VALUES + (1, 'Gasoline', 'Gasoline', 93.67, TRUE), + (2, 'Diesel', 'Diesel', 100.21, TRUE), + (3, 'Jet fuel', 'Jet fuel', 88.83, TRUE) + ON CONFLICT (fuel_category_id) DO NOTHING; + """) + # Fuel Types op.execute(""" INSERT INTO fuel_type (fuel_type_id, fuel_type, fossil_derived, other_uses_fossil_derived, @@ -229,6 +209,45 @@ def upgrade() -> None: ON CONFLICT (fuel_type_id) DO NOTHING; """) + # Energy Effectiveness Ratios + op.execute(""" + INSERT INTO energy_effectiveness_ratio ( + eer_id, fuel_category_id, fuel_type_id, end_use_type_id, ratio, effective_status + ) + VALUES + (1, 1, 2, NULL, 0.9, TRUE), + (2, 1, 3, 1, 3.5, TRUE), + (3, 1, 3, 2, 1.0, TRUE), + (4, 1, 6, 3, 2.4, TRUE), + (5, 1, 6, 2, 0.9, TRUE), + (6, 1, 13, NULL, 0.9, TRUE), + (7, 2, 2, NULL, 0.9, TRUE), + (8, 2, 3, 4, 3.8, TRUE), + (9, 2, 3, 5, 3.2, TRUE), + (10, 2, 3, 6, 2.5, TRUE), + (11, 2, 3, 7, 2.9, TRUE), + (12, 2, 3, 8, 2.5, TRUE), + (13, 2, 3, 9, 3.9, TRUE), + (14, 2, 3, 10, 2.8, TRUE), + (15, 2, 3, 11, 2.4, TRUE), + (16, 2, 3, 2, 1.0, TRUE), + (17, 2, 6, 3, 1.8, TRUE), + (18, 2, 6, 2, 0.9, TRUE), + (19, 2, 13, NULL, 0.9, TRUE), + (20, 3, 3, NULL, 2.5, TRUE), + (21, 3, 11, NULL, 1.0, TRUE), + (22, 2, 7, 15, 1.0, TRUE), + (23, 2, 7, 16, 1.0, TRUE), + (24, 2, 7, 17, 1.0, TRUE), + (25, 2, 7, 18, 1.0, TRUE), + (26, 2, 7, 19, 1.0, TRUE), + (27, 2, 7, 20, 1.0, TRUE), + (28, 2, 7, 21, 1.0, TRUE), + (29, 2, 7, 22, 0.9, TRUE), + (30, 2, 7, 23, 0.9, TRUE) + ON CONFLICT (eer_id) DO NOTHING; + """) + # Now Additional Carbon Intensities op.execute(""" INSERT INTO additional_carbon_intensity (additional_uci_id, fuel_type_id, uom_id, end_use_type_id, intensity) @@ -269,16 +288,6 @@ def upgrade() -> None: ON CONFLICT (energy_density_id) DO NOTHING; """) - # Fuel Categories - op.execute(""" - INSERT INTO fuel_category (fuel_category_id, category, description, default_carbon_intensity, effective_status) - VALUES - (1, 'Gasoline', 'Gasoline', 93.67, TRUE), - (2, 'Diesel', 'Diesel', 100.21, TRUE), - (3, 'Jet fuel', 'Jet fuel', 88.83, TRUE) - ON CONFLICT (fuel_category_id) DO NOTHING; - """) - # Target Carbon Intensities op.execute(""" INSERT INTO target_carbon_intensity ( From c7e464b4d1cc5553bd3c227a7d1f96f9c9307a85 Mon Sep 17 00:00:00 2001 From: Kevin Hashimoto Date: Thu, 2 Jan 2025 15:06:38 -0800 Subject: [PATCH 4/5] fix: move expected use to migration file --- .../versions/2024-12-24-07-40_d9cdd9fca0ce.py | 10 +++++ .../seeders/dev/expected_use_types_seeder.py | 42 ------------------- backend/lcfs/db/seeders/dev_seeder.py | 5 +-- 3 files changed, 12 insertions(+), 45 deletions(-) delete mode 100644 backend/lcfs/db/seeders/dev/expected_use_types_seeder.py diff --git a/backend/lcfs/db/migrations/versions/2024-12-24-07-40_d9cdd9fca0ce.py b/backend/lcfs/db/migrations/versions/2024-12-24-07-40_d9cdd9fca0ce.py index ea13eb70f..6b4bb1614 100644 --- a/backend/lcfs/db/migrations/versions/2024-12-24-07-40_d9cdd9fca0ce.py +++ b/backend/lcfs/db/migrations/versions/2024-12-24-07-40_d9cdd9fca0ce.py @@ -122,6 +122,15 @@ def upgrade() -> None: """) # 9. Static Fuel Data + # Expected Use Types + op.execute(""" + INSERT INTO expected_use_type (expected_use_type_id, name, description, effective_status) + VALUES + (1, 'Heating oil', 'Fuel used for heating purposes', TRUE), + (2, 'Other', 'Other type of fuel description', TRUE) + ON CONFLICT (expected_use_type_id) DO NOTHING; + """) + # Unit of Measures first op.execute(""" INSERT INTO unit_of_measure (uom_id, name, description) @@ -557,6 +566,7 @@ def downgrade() -> None: # Group 4 - Base reference tables (no dependencies) [ + 'expected_use_type', 'unit_of_measure', 'provision_of_the_act', 'initiative_agreement_status', diff --git a/backend/lcfs/db/seeders/dev/expected_use_types_seeder.py b/backend/lcfs/db/seeders/dev/expected_use_types_seeder.py deleted file mode 100644 index 6914a3e57..000000000 --- a/backend/lcfs/db/seeders/dev/expected_use_types_seeder.py +++ /dev/null @@ -1,42 +0,0 @@ -import structlog -from sqlalchemy import select -from lcfs.db.models.fuel.ExpectedUseType import ExpectedUseType - -logger = structlog.get_logger(__name__) - - -async def seed_expected_use_types(session): - """ - Seeds initial expected use types into the database, if they do not already exist. - Args: - session: The database session for committing the new records. - """ - - expected_use_types_to_seed = [ - {"name": "Heating oil", "description": "Fuel used for heating purposes"}, - {"name": "Other", "description": "Other type of fuel description"}, - ] - - try: - for expected_use_type_data in expected_use_types_to_seed: - # Check if the expected use type already exists - exists = await session.execute( - select(ExpectedUseType).where( - ExpectedUseType.name == expected_use_type_data["name"] - ) - ) - if not exists.scalars().first(): - expected_use_type = ExpectedUseType(**expected_use_type_data) - session.add(expected_use_type) - - except Exception as e: - context = { - "function": "seed_expected_use_types", - } - logger.error( - "Error occurred while seeding expected use types", - error=str(e), - exc_info=e, - **context, - ) - raise diff --git a/backend/lcfs/db/seeders/dev_seeder.py b/backend/lcfs/db/seeders/dev_seeder.py index 993e58ab0..f298ab827 100644 --- a/backend/lcfs/db/seeders/dev_seeder.py +++ b/backend/lcfs/db/seeders/dev_seeder.py @@ -22,7 +22,6 @@ from lcfs.db.seeders.dev.feedstock_fuel_transfer_mode_seeder import ( seed_feedstock_fuel_transfer_modes, ) -from lcfs.db.seeders.dev.expected_use_types_seeder import seed_expected_use_types logger = structlog.get_logger(__name__) @@ -44,7 +43,8 @@ async def update_sequences(session): for table, column in sequences.items(): sequence_name = f"{table}_{column}_seq" max_value_query = text( - f"SELECT setval('{sequence_name}', COALESCE((SELECT MAX({column}) + 1 FROM {table}), 1), false)" + f"""SELECT setval('{sequence_name}', COALESCE((SELECT MAX({ + column}) + 1 FROM {table}), 1), false)""" ) await session.execute(max_value_query) @@ -63,7 +63,6 @@ async def seed_dev(session: AsyncSession): await seed_fuel_codes(session) await seed_finished_fuel_transfer_modes(session) await seed_feedstock_fuel_transfer_modes(session) - await seed_expected_use_types(session) # Update sequences after all seeders have run await update_sequences(session) From dcf89678d1005c530adf8304a61873a6f364334d Mon Sep 17 00:00:00 2001 From: Kevin Hashimoto Date: Thu, 2 Jan 2025 15:33:23 -0800 Subject: [PATCH 5/5] fix: backend tests --- .../db/migrations/versions/2024-12-24-07-40_d9cdd9fca0ce.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/lcfs/db/migrations/versions/2024-12-24-07-40_d9cdd9fca0ce.py b/backend/lcfs/db/migrations/versions/2024-12-24-07-40_d9cdd9fca0ce.py index 6b4bb1614..e865535c4 100644 --- a/backend/lcfs/db/migrations/versions/2024-12-24-07-40_d9cdd9fca0ce.py +++ b/backend/lcfs/db/migrations/versions/2024-12-24-07-40_d9cdd9fca0ce.py @@ -10,7 +10,7 @@ # revision identifiers, used by Alembic. revision = "d9cdd9fca0ce" -down_revision = "5fbcb508c1be" +down_revision = "ab04810d4d7c" branch_labels = None depends_on = None