admin / Apex
publicBid Management and Orchestration Tool with AI Capability
Apex / Synapse-Apexv2 / backend / app / core / seed.py
5913 B · main
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 | from decimal import Decimal from sqlalchemy import select from sqlalchemy.orm import Session from app.core.config import settings from app.core.security import hash_password from app.models import ( ROLE_ADMIN, ComplianceFramework, EffortRule, LicenceCost, ResourceType, User, WorkflowTemplate, ) FRAMEWORKS = [ ("ISO 27001", "Information security management system controls (Annex A)."), ("ISO 9001", "Quality management system requirements."), ("Cyber Essentials Plus", "UK NCSC baseline technical controls, independently verified."), ("NIST CSF", "Identify, Protect, Detect, Respond, Recover functions."), ("SOC 2", "Trust Services Criteria: security, availability, confidentiality."), ("GDPR / DPA 2018", "UK data protection principles and obligations."), ] RESOURCE_TYPES = [ ("Service Desk Analyst", "Support", 28, 55, "L1/L2 support, ITIL"), ("Network Engineer", "Infrastructure", 45, 85, "Cisco, firewalls, LAN/WAN"), ("Security Analyst", "Security", 50, 95, "SIEM, incident response"), ("Service Delivery Manager", "Management", 55, 110, "ITIL, governance, SLA"), ("Cloud Engineer", "Cloud", 55, 100, "Azure, AWS, IaC"), ("Project Manager", "Management", 55, 105, "Prince2, transition"), ] EFFORT_RULES = [ ("Service desk per 100 workstations", "per_endpoint", "workstations", 100, "Service Desk Analyst", 32, 0), ("Security monitoring per 100 servers", "per_endpoint", "servers", 100, "Security Analyst", 20, 0), ("Network support per site", "per_site", "sites", 1, "Network Engineer", 8, 16), ("Service delivery management (fixed)", "fixed", None, 1, "Service Delivery Manager", 34, 0), ("Transition project management (fixed)", "fixed", None, 1, "Project Manager", 0, 160), ] LICENCES = [ ("Endpoint protection", "Vendor A", "per_endpoint", 4.5, "monthly"), ("SIEM ingestion", "Vendor B", "per_endpoint", 2.0, "monthly"), ("RMM agent", "Vendor C", "per_endpoint", 1.25, "monthly"), ] DEFAULT_WORKFLOW = { "name": "Standard bid workflow", "is_default": True, "stages": [ {"key": "draft", "label": "Draft", "roles": ["bid_manager"]}, {"key": "planning", "label": "Planning", "roles": ["bid_manager"]}, {"key": "in_progress", "label": "In progress", "roles": ["bid_manager", "contributor"]}, {"key": "in_review", "label": "In review", "roles": ["approver"]}, {"key": "approved", "label": "Approved", "roles": ["approver"]}, {"key": "submitted", "label": "Submitted", "roles": ["bid_manager"]}, ], "milestones": [ {"name": "Kick-off", "offset_working_days_before_submission": 0, "from": "start"}, {"name": "Requirement review complete", "offset_working_days_before_submission": 18}, {"name": "First drafts complete", "offset_working_days_before_submission": 12}, {"name": "Red-team / quality review", "offset_working_days_before_submission": 6}, {"name": "Pricing complete", "offset_working_days_before_submission": 5}, {"name": "Approval", "offset_working_days_before_submission": 3}, {"name": "Submission", "offset_working_days_before_submission": 0}, ], } def _first(db: Session, model): return db.execute(select(model).limit(1)).scalar_one_or_none() def run_seed(db: Session) -> None: # Admin user admin = db.execute( select(User).where(User.email == settings.admin_email) ).scalar_one_or_none() if not admin: db.add( User( email=settings.admin_email, name="Administrator", password_hash=hash_password(settings.admin_initial_password), roles=[ROLE_ADMIN], is_active=True, must_change_password=True, ) ) if not _first(db, ComplianceFramework): for name, desc in FRAMEWORKS: db.add(ComplianceFramework(name=name, description=desc, controls=[], active=True)) rt_map = {} if not _first(db, ResourceType): for name, fam, cost, sell, skills in RESOURCE_TYPES: rt = ResourceType( name=name, role_family=fam, skills=[s.strip() for s in skills.split(",")], hourly_cost_rate=Decimal(str(cost)), hourly_sell_rate=Decimal(str(sell)), daily_cost_rate=Decimal(str(cost * 8)), daily_sell_rate=Decimal(str(sell * 8)), currency=settings.default_currency, ) db.add(rt) db.flush() rt_map[name] = rt.id else: for rt in db.execute(select(ResourceType)).scalars(): rt_map[rt.name] = rt.id if not _first(db, EffortRule): for name, trig, etype, qty, rtname, rec, one in EFFORT_RULES: db.add( EffortRule( name=name, trigger=trig, endpoint_type=etype, per_qty=Decimal(str(qty)), resource_type_id=rt_map.get(rtname), hours_recurring=Decimal(str(rec)), hours_oneoff=Decimal(str(one)), active=True, ) ) if not _first(db, LicenceCost): for name, vendor, unit, cost, billing in LICENCES: db.add( LicenceCost( name=name, vendor=vendor, unit=unit, unit_cost=Decimal(str(cost)), billing=billing, active=True, ) ) if not _first(db, WorkflowTemplate): db.add( WorkflowTemplate( name=DEFAULT_WORKFLOW["name"], is_default=True, stages=DEFAULT_WORKFLOW["stages"], milestones=DEFAULT_WORKFLOW["milestones"], ) ) db.commit() |