{% extends "network/base.html" %} {% block title %}{{ project.name }} — Project{% endblock %} {% block content %}
{{ topologies|length }}
Topologies
{{ circuits|length }}
Circuits
{{ agg_compliance_pct if agg_compliance_pct is not none else '—' }}{% if agg_compliance_pct is not none %}%{% endif %}
Compliance Score
{{ total_open_findings }}
Open Findings
${{ total_capex|round(0)|int }}
Est. CapEx
${{ total_circuit_cost|round(0)|int }}/mo
Circuit OpEx
{{ project.owner or '—' }}
Owner

Review Board Pipeline

{% if not project_phases %}{% endif %}
{% if project_phases %}
{% for ph in project_phases %}
{{ ph.phase_num }}
{{ ph.phase_name }}
{% if not loop.last %}
{% endif %} {% endfor %}
{% endif %}
{% for board in review_boards %}
{{ board.short_name }} {{ board.name }} {% if board.is_optional %}Optional{% endif %}
{% set ns = namespace(found=false) %} {% for br in board_reviews if br.board_id == board.id %} {% set ns.found = true %}
Phase {{ br.phase }}
{{ br.status }}
{% if br.decision_notes %}
{{ br.decision_notes[:60] }}
{% endif %} {% if br.status == 'pending' %}
{% endif %}
{% endfor %} {% if not ns.found %}
No reviews submitted
{% endif %}
{% endfor %}
{% if safe_bridge and safe_bridge.roi %}
CapEx: ${{ (safe_bridge.roi.capex or 0)|round(0)|int }}
Annual OpEx: ${{ (safe_bridge.roi.opex_annual or 0)|round(0)|int }}
Annual Savings: ${{ (safe_bridge.roi.savings_annual or 0)|round(0)|int }}
Payback: {{ safe_bridge.roi.payback_months or 0 }} months
5-Year NPV: ${{ (safe_bridge.roi.npv_5yr or 0)|round(0)|int }}
{% if safe_bridge.justification %}
Justification: {{ safe_bridge.justification[:200] }}
{% endif %}
{% endif %}

AI-Generated Courses of Action

HITL Review → Select → AI regenerates plan {% if first_topo_id %} 🗺 Phase Diagrams {% endif %}
{% set coas = [ ('coa_1', '#e74c3c', 'high', 'Rip & Replace', '2–4h', '1 day', 'Swap hardware in single window. Fastest, highest risk.'), ('coa_2', '#f39c12', 'medium', 'Phased Cutover', '5–15 min/phase', '2 weeks', 'Migrate per circuit over 1–2 weeks. Balanced risk.'), ('coa_3', '#27ae60', 'low', 'Side-by-Side VLAN', 'Near-zero', '3 weeks', 'Old + new parallel on same VLAN. Safest. Recommended.') ] %}
{% for key, color, risk, name, downtime, duration, desc in coas %} {% set coa_obj = coa_data.get(key, {}) %} {% set is_selected = project.selected_coa == coa_obj.get('id', loop.index) %}
{% if is_selected %}
SELECTED
{% endif %}
{{ name }}
{{ risk }} risk
{{ desc }}
Downtime: {{ downtime }}
Duration: {{ duration }}
{% endfor %}

Migration Plan

Migration Hub {% if first_topo_id %} 3-Panel Diagram {% endif %}
{% if migration_phases %} {% for ph in migration_phases %}
{{ ph.phase_num }}
{{ ph.title or 'Phase ' ~ ph.phase_num }}
{{ (ph.status or 'pending')|title }} {% if ph.duration_days %}{{ ph.duration_days }}d{% endif %}
🕐 Window: {{ ph.maintenance_window or 'TBD' }}
{% if ph.rollback_criteria %}
↩ Rollback: {{ ph.rollback_criteria }}
{% endif %} {% if ph.dependencies and ph.dependencies != '[]' %}
⛔ Depends on: {{ ph.dependencies }}
{% endif %}
{% if ph.steps %}
    {% for step in ph.steps %} {% if step %}
  • {{ loop.index }}
    {{ step }}
  • {% endif %} {% endfor %}
{% endif %} {% if ph.linked_docs %}
📄 Reference SOPs ({{ ph.linked_docs|length }})
{% for doc in ph.linked_docs %}
{{ (doc.doc_type or doc.doc_source or 'SOP')|upper }} {{ doc.doc_title }} {% if doc.steps %}{{ doc.steps|length }} steps ▾{% endif %} {% if doc.relevance_note %}{{ doc.relevance_note }}{% endif %}
{% if doc.steps %}
{% if doc.prerequisites %}
Prerequisites: {% for p in doc.prerequisites %}{{ p }}{% endfor %}
{% endif %} {% for step in doc.steps %}
{{ step.number }}.
{{ step.text }}
{% if step.verify %}
✓ {{ step.verify }}
{% endif %}
{% if step.time_est %}{{ step.time_est }}{% endif %}
{% endfor %}
{% endif %}
{% endfor %}
{% endif %}
{% endfor %} {% else %}
No migration phases defined for this project. Create one in the Migration Hub →
{% endif %}

Port Mapping & Config Translation

{% if target_device_id %}
Device: {{ target_device_id }} → AI-mapped to replacement
{% endif %}
{% if port_mapping.port_mappings %}
AI-Generated Port Mapping
{% for pm in port_mapping.port_mappings %} {% endfor %}
Old PortNew PortService / RoleStatus
{{ pm.old_port }} {{ pm.new_port }} {{ pm.service }} {% if pm.status == 'mapped' %} Auto {% else %} Manual {% endif %}
{{ port_mapping.mapped_count or 0 }} auto-mapped
{{ port_mapping.unmapped_count or 0 }} manual
{% if port_mapping.conflicts %}
{{ port_mapping.conflicts|length }} conflicts
{% endif %}
{% else %}

No port mapping data available. Select a COA above to trigger AI generation.

{% endif %} {% if config_translation.lines %}
Config Translation ({{ config_translation.source_vendor }} → {{ config_translation.target_vendor }}) — Confidence {{ (config_translation.confidence * 100)|round(0)|int }}%
Original Config
{% for line in config_translation.lines[:80] %}{% if not line.changed %}{{ line.old }}
{% endif %}{% endfor %}
Translated Config
{% for line in config_translation.lines[:80] %}{% if line.changed %}
{{ line.new }}{% else %}{{ line.new }}{% endif %}
{% endfor %}
{% if config_translation.notes %}
{% for note in config_translation.notes %}
{{ note }}
{% endfor %}
{% endif %}
{% endif %}

Compliance Rollup

{% if topo_compliance %} {% for tc in topo_compliance %} {% endfor %}
TopologyScorePassedFailed CAT1CAT2CAT3OpenLast Audit
{{ tc.name }} {% if tc.pct is not none %} {{ tc.pct }}% {% else %}—{% endif %} {{ tc.passed }} {{ tc.failed }} {% if tc.cat1 > 0 %}{{ tc.cat1 }}{% else %}0{% endif %} {% if tc.cat2 > 0 %}{{ tc.cat2 }}{% else %}0{% endif %} {{ tc.cat3 }} {% if tc.open_findings > 0 %}{{ tc.open_findings }}{% else %}0{% endif %} {{ (tc.last_audit or '')[:16] }}
AGGREGATE {% if agg_compliance_pct is not none %} {{ agg_compliance_pct }}% {% else %}—{% endif %} {{ topo_compliance|sum(attribute='passed') }} {{ topo_compliance|sum(attribute='failed') }} {{ topo_compliance|sum(attribute='cat1') }} {{ topo_compliance|sum(attribute='cat2') }} {{ topo_compliance|sum(attribute='cat3') }} {{ total_open_findings }}
{% else %}

No compliance audits run yet. Open a topology and run a compliance audit.

{% endif %}

Topologies

{% if topologies %} {% for t in topologies %} {% endfor %}
NameNodesLinksAssigneeUpdatedActions
{{ t.name }} {{ t.node_count }}{{ t.edge_count }} {{ topo_assignees.get(t.id, '—') }} {{ (t.updated_at or '')[:16] }} C V
{% else %}

No topologies linked. Click "+ Link Topology" to add one.

{% endif %}

Cost Rollup

{% for tb in topo_bom %} {% endfor %}
TopologyDevicesUnique TypesEst. CapEx
{{ tb.name }} {{ tb.devices }} {{ tb.unique_types }} ${{ tb.capex|round(0)|int }}
TOTAL ${{ total_capex|round(0)|int }}
Circuit OpEx (monthly) ${{ total_circuit_cost|round(0)|int }}/mo
{% if circuits %}

Circuits

{% for c in circuits %} {% endfor %}
Circuit IDCarrierTypeBWStatusCost/mo
{{ c.circuit_id }}{{ c.carrier }}{{ c.circuit_type }}{{ c.bandwidth }} {{ c.install_status }}${{ (c.monthly_cost_usd or 0)|round(0)|int }}
{% endif %}

Milestones

{% if milestones %} {% for m in milestones %}
{{ m.title }}
{% if m.due_date %}
Due: {{ m.due_date }}
{% endif %} {% if m.notes %}
{{ m.notes }}
{% endif %}
{% endfor %} {% else %}

No milestones. Click "+ Add" to track deadlines.

{% endif %}
{% if milestones %}
{% for m in milestones if m.due_date %}
{{ m.title[:20] }} {{ m.due_date }}
{% endfor %}
{% endif %}

Tags

{% for tag in project_tags %} {{ tag }} {% endfor %}

Status Gates

Check readiness before changing status:

Notes

{% for n in notes %}
{{ n.author or 'Anonymous' }} · {{ (n.created_at or '')[:16] }}
{{ n.body }}
{% endfor %}

Activity Feed

{% if activity %}
{% for a in activity %}
{{ a.action }} {{ a.entity_type }}
{% if a.details %}
{{ a.details[:80] }}
{% endif %}
{% if a.user_id %}{{ a.user_id[:20] }}{% endif %} {{ (a.ts or '')[:16] }}
{% endfor %}
{% else %}

No activity recorded yet.

{% endif %}
{% endblock %} {% block scripts %} {% endblock %}