Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .abacus.donotdelete

Large diffs are not rendered by default.

21 changes: 21 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,11 @@ pg_dump_*
test_output/
*.out
*.log
# Migration engine runtime artifacts (relocated under backend/migration/)
csv/logs/
evals/reports/
backend/migration/build/csv/logs/
backend/migration/evals/reports/
*_report_*.txt
*_skipped_*.csv
*_valid_*.csv
Expand Down Expand Up @@ -48,6 +51,24 @@ terraform-github-repos/*.tfstate.*
terraform-github-repos/crash.log
.abacusai/

# --- MEP v2 (Migration Evaluation Platform) ---
# Node / React frontend
node_modules/
frontend/node_modules/
frontend/build/
frontend/dist/
frontend/.next/
npm-debug.log*
yarn-error.log*
# Python bytecode / virtualenvs
__pycache__/
*.py[cod]
.env
.env.*
# CSV upload staging (keep the directory, ignore its contents)
uploads/*
!uploads/.gitkeep

# Terraform plan artifacts (binary, environment-specific, never commit)
*.tfplan
tfplan
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0
48 changes: 47 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,50 @@
# T&E Database Framework
# Migration Evaluation Platform (MEP) v2

> **MEP** is a web application that wraps the existing CSV → PostgreSQL migration engine
> with a **React frontend** and a **FastAPI backend**, turning a powerful CLI/script-based
> tool into an interactive platform for **uploading CSV files, running migrations, and
> evaluating migration quality** (completeness, integrity, business-rule conformance, and
> reconciliation reporting).

[![Status](https://img.shields.io/badge/MEP-v2%20(in%20development)-blueviolet)](#)
[![Backend](https://img.shields.io/badge/Backend-FastAPI-009688?logo=fastapi&logoColor=white)](#)
[![Frontend](https://img.shields.io/badge/Frontend-React-61DAFB?logo=react&logoColor=white)](#)
[![Engine](https://img.shields.io/badge/Engine-CSV%20%E2%86%92%20PostgreSQL-336791?logo=postgresql&logoColor=white)](backend/migration/)

## What MEP Is

The **Migration Evaluation Platform** does not replace the proven migration engine — it
**wraps** it. The original, battle-tested SQL-first framework and CSV → PostgreSQL
loader/validator pipeline now lives, unchanged, at **[`backend/migration/`](backend/migration/)**.
The FastAPI backend shells out to / orchestrates that engine rather than reimplementing it,
and a React frontend provides a UI for the full migrate-and-evaluate workflow.

### Repository layout (MEP v2)

```
PostgreDataMigrationApp/
├── backend/
│ ├── api/ FastAPI routes (HTTP layer)
│ ├── services/ Business logic
│ ├── migration/ ← ORIGINAL migration engine (build/ evals/ infra/ tests/), preserved
│ ├── evaluation/ Migration-quality evaluation logic
│ ├── reports/ Reconciliation / evaluation report generation
│ └── database/ MEP metadata models (MigrationRun, UploadedFile, ...)
├── frontend/ React app
├── docker/ Dockerfiles / compose
├── docs/ Documentation
├── uploads/ CSV upload staging
└── .github/ CI workflows
```

> **Original engine:** everything that shipped before MEP — the multi-engine database
> framework, the CSV pipeline, the 23 eval scenarios, the 85 SQL assertions, and the Azure
> IaC — is preserved verbatim under **[`backend/migration/`](backend/migration/README.md)**.
> The documentation below describes that original engine.

---

# T&E Database Framework (original engine — now under `backend/migration/`)

> A fully parameterised, idempotent **PostgreSQL database framework** for **Test & Evaluation (T&E)** programme management — covering TEMP documents, VCRM traceability, test execution, defect reporting, and multi-environment deployment, with a built-in SQL test suite.

Expand Down
1 change: 1 addition & 0 deletions backend/.abacus.donotdelete
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
gAAAAABqVibVniO0KajGcO16Z2DqpjOsoz_Wwk-hlK9h55ElasbUvl4iTms8CgWxLyIWlmajRqbRNtlFNceS2bR4o1kKdK2nib9It0X3o1c34pJjYBC9oChcduhdGK_hA4mWGMRPGXtCgyc4lLTVE5RM21CmiEsjT-DWcI48t3iJFE92mzBEYfyIGG5oVaIF3pKHeBTenmEhmmj7Dp5tqNxCRk1sS9zcZdZU2Klx-vF_0VzjCLuR2zRgj8nZQyeaUpGRlg0fhKMPwvrOCEsi9CtYxB_-IVQUAPvXbOYNAs-MsVfexG2hhNiF43wNDXjm3YSLmlFno0kYPdoDOWBVPwzfRv_VfJZ2D97wAV7Br6zXzSdLw5sZ7NrAosR6Y0nFfz6qXMbS1shhPAI3tZVBTHMZenJomS8pliMo0MiaciortzmqUyr1_dw2yFXkg8XN-MGKgwvHS9EkrRQEZEQxvXzDImotMdRU576oVI7qlrIizTnndguWzjlttgVdX74XiGnHJP8ViddRZ8D9qp1_CbY5oNXUXRWrZaoNvN1HHOnSw7eg8JWZFIXmxuNsvWEFnjA4NRqYWwK3vHfmtFvSHi070JFAXCquFlaTnz6Wk4YwlfAvnsjiM5-I4lCWe30ze01Q3oS2xjPWVQExROIuPQhmHBDgSl-HFj5w_9KXRtf_AU_cxzYRYIYOsyr1t5Z74FBaSoDBjtRFX1FLu53xifRSLAz0b8tW-ZQwOK9T03pYQGd0-R73-P8-GUVrz3wJBPf2sfxEXbYrpOEDLOPBqIeA0iTaSLB3jm0ptMYgLOs06kdbFok8CZ4sinqkpk8vAqYO0BAAZ8CPGnt-30PLnf-6iRHmwMHoKie1QZKp2xssV_mRyZbUvJOd9_UJP1hmp-D9b2le72tiYJXIBdNy7cMfmt1FLodxK3KX3Hk3wkGUwPJjkyJJKxIYaH7GnJwQ5mA-IhufjfCpzGRIUpX0-UBQtJVfJrr5xWaJNO0DTdMXDmBipmA7DthHMyXIk4IxhOZi4M7huhnlS68J-5D8h1QL6DGSrhqOAmyMxd623qC224cpalNI7Y-fDm9eO2_IN3QwPL3M7ba087T2k29VY05B9RxHHaJKV5sflZ9nJzIV8XE8LyCtn2p-_o_I6YOUlSoZeFZmSB9g3ulCV4s0hGrL6xqftdL0Dq03cHkrS_xGWQqiMHXDtmrhigq3OelNv-QTLe46nMhqviE-1oUUk9uetVnF2bzJA-DwT-mQMjxr0MyuNT69NSja-xt61KuIEdW0aA4pBr5McCmyQ1Nr-3FH2XAgW82CSFydVlnB2pXnbYM1kdAtLzHVMpTyoXV2GT9j2zHbsuyIXiULpsekGnDgePTxBiqTmlD9pwUFbzZ4zemRz6SAmZRVIXI_T4UDXUeaGa9bK2-Fmcwl4ZtJJRLmbINpNBVF4FYX9GYE3vGC34XIzB67u2O2_tIaii_CzG_oG6tjIqepoD79ArwaILOy-6EgRXcWhmbaZnn7vbogz-ayHhE9QB_anAfDZ0cXbdyyd8-T36SUkpM4GNwkejtt4VfkI6kmivN3PDfZN5N59n-S6eqOI8p7aiwo6DOkDZ4h4OBM02wVF1MeIQ63wnV3kwDI-UdJ90WKoJEFQPdFOIegGHjUITS8Zt3sWEMp59GmEO_ekIbtHtvhSKGg5PzuyJF0_CXKhfW1H92p5kvpeH8eSbqBvrGGR89F-uOhwbq17rSA_m5tNcY3L53xGXREnyeUo9iBP19hvNZPYdqYhDRzwJvjACqNhMEzSjIklgW15QFyAs-Xh9phCGdmFvLQaapmTSFmA6--cD0w6BrmoEVyZ91lYhthVf_-3QVbPEdGNyEmWkw4Oi1r6fkwdIFh7DHZQwua8WeHFMwqklxBuWxV-VGs-FdAPbO850MeSBW3pyJXSOYcDkEk2VHXbMnP5E8Z25_QCKk-jv_liGG13vEMgMZ0U7lqbJCTFKnTDooA2MM8NE_Nxfy7phHk17RbeAksst0eMHvTaU33399S8FRC8U3wMGG_rGl8TA2QAaRk4NOCuthcrO7yMXyoxQbRph8C24tDviTT8c21dnbdvZAJOAXXDjEWvk1SzlfVHe5S7rc0jo9i1b0R5Ijia4e3M7ZMdrCrDpEMA0oUj8Q6pDEaEnCe-AjrQuUGB1vpxxZRSWzJyMwHZ0WKq5xzm6RQZMeNI7_nENDWpbTAAOZIY4gDRlRGBbI5VPYSEfxQSPG8egmwwB2odnTUJUi28y_72al1bdiNOMCcTuqp8LBwZwGkRJYeHjZG3sShIDA_yeeROgQShg35sjbrOGc5pdZ3USZ4xJY66HKSMTOw2cdZDilUJpBscsat4SCajjUekZBybZZLHGHnSW4pJInhr2Vj6sySH1GtnAQHFwmmsB0tqmD37AldEAGRwiQOrKHyo7ueARipVYz_6PkEMjp1VkVGCPehakW3atQ_yApqPzvEm_OlxWdBTiB1sVc_paEteobEuMQrSvImpJBMjRlxJXkuMDl6axw9Sjy0viXrYBi70PdEayQm0SIDQSOvyMq78gMEHDVPF7XIkZSPMgfBPFnBxpFBjphkxcROqAE97pCjqnwvtjYzEz4pWauzy1A4URXnsdRN3zVsBXflqm0vgYUMxX7OsMg8-Eh9fPQ4tVPupO-l3ERWV-NoEgCmslQQ2g78g1n6cECq4vpdnFebo1oZFAv71OH59W2u6xcUi_a5WZkmD9Fumgg4fOlXvc7hzUBdxfbxsOEW3feg2N2Mv1a3DqNyhtq_B_pitJ4zWFYH7VWyVAYHyeazmbnSEbHhg0hG2uHOWAiBKAET5jcESjq9ONK41Dm4PuTx-JICq9WHP7Iumyx3qR8YMePDsxFmCPPlWq7KOfPawx7HALfg9cj3woERz6CgDAzqH01Zmbsn6tATMxiQFEcImkm1ymCKMvULvs8OylQAK6ypxBsSkSYViMvIqmwFdIUMMKv_-9DXdxts55tbrUb--owC5td0ynfeIscUFqTmT2Mcwo8xvO1kme8MrQevKoXJy1Ohx6vrAGIl6QqU4Xm-UAF7L2eJh6iYQCtAMOJn6caAr5bCxOdmSfzcFjLMW6udjdh7O53FO7f2V6gHhjMi-mfGS5j5mksvx_luKlxpiUhm_lsiHuSE5ZlKqjIpffWT3l4LeTlp8-Xw2OIJQzM6hYMdjiEx7TGja9kpLsefHp30UH6Eg4aO0AukIynTHOGP5HVW8SU7JIRZWuejkIfdcFSoDjCj7SsTJzk67PcwzPZkhi4kjLAwnDv_w-6LfMlzwcyYn7O8pbIAL63kdfJomI-jScN1ySRE9a1J0pBt6BUMvFLLwhkNxGTzamM-BwUOTQ2KXIjrk08lw-ct4pdy9amtFC_Olsj7FmCS5zuGzQXvMniH1is5co7LwnmEPlw3ecy6ASj0-QZW_83JR7Z8_K6RV4KykGt71BavEfIbY5KJJgiia9bwhAkcPR3ZtRKEHg6uLrBXPG60i3_yziKN0miyLq9sMkM94si8PmYuWNEF_496ajwZKazQ6oT13TWayj4O85JnJDOBV0PQXXNiU0flovBWY5w0SKPWbR3f3r1fdsepqAflakjRP9224dMK8CGVaE2bHWnTuPheIk8Fd-go2wbBCHYDKo7G_Hpyib3p2CxCjhKHzbEB0IuuSU4U4OtVauGoOL_0mKP-Pn8DyIRBNoFaOuL8wWbKaTsPRz-S8vkreeJx512aXXE6UNhIHgQ4GkekG1vy0u-0pioR2BtkXz1vIkEOxEmbchKoxdtoeahNshGFMQW6qOryJbgVg5VTsKAIUe_Fa0LGzEmut1_R9_932JKGGho3tajE8pgBR78_gPF7ntMT9tbClgECxz5KzJ_GCu_RLJb6xzVrLFMVTubmESNBWtz2uU6Zd3-t_jPsdqv_ehM2uBgnYdZc7RykXnNDkBCT38NfEzUi-2Rso6OO2wonUBf-bZ_Vx9N6fxnrohCNAqFenhT76KHOTYHQJyLTFUlGaxdFlobhq4upkN-G6TC2oaSc2rq5NmtDdy0CKIoz6Uc4dESJestLgVpNEI-TN0JUEBJlheBeCZBFFOnah4j_Bt6vfmBbzZLiX9U7LUjS_ERBGCqDRds8rNW5u7y31TmVyskP_rAbIrTQp8oRkfm1pj9rjJGzZqr8xGsmZoqlXMmNzTRrj2nmPevBh2Hg6S69HX0nDIxaHzZzfmh7t-_OuGEqD-VMg3fG9BLIVdmYDZQgsfYopolcDQPNUvDoffkIzSZoncmyOnqq1x9iepJKRMXp-ctv7kl1ADxIzh953IGUbv5SrN3W8Pr5U5thnmq3atRUKgByGiqCEVprwLy_Yr_cVnDrgKpc81f1drCKFSHNcy3dOsIQF57HaG4NV7F7kO3_N_z5xG90CvLRgSshKzGFgHi0nHSOm9zzjrbamw5njXWeBit7FgJnpyWyaRy4t7PqIJdIKBNUO7Lw03Wtu8mpATtrxWoaOVmC8J53v5imO8quHd1RlK8CRbkHPWcMbFA71mLY_oIFb-_AQK7lmM2L1b5FUa8fDTki5htzGFdhofnRg-AHHiIR0tKPJ5W5oMLHUfON52mokUhMXZ8sN7QSeOwkfrNeVF15_CX8cVJ7qqC1_jxWG0EceYTukaKx8WfzfAP6iEKklGSxasVo2WYHtkSzVgzBlZo7fpCWUkG9rqDmKgFzE7wwz8S1B1iRfj67Ja3e14Wc3alcmiyT3odw3f2L5tfojonLuLoQvRcCoKuf3qDDgk-tw1KVpJS8VyDlrOHKHfAya__4mWqXNIOtjoVGCzoI1WyUgDu7Cxn21uR4bBH5JPo3fBZ1NcfEbHfEJhxfqYo2sdpw1-_VFZPfBTjczZpmO62JxS6maJaUekSGLA0wqtFuE0vRocV0g9JEPYd8OSN27c94gBfgKxgDPrF5yRWVSmVZJyn5TLZQgIUNtqwqmI1Lo5U7-iwEMwhvjYCr61zmCkS2HKnB8AFHh6kNEUUftqM9LbJj2BmEcy9xmPyETN7JNr77fFVDlQmgFFZaIlKa3Y09kHegx08HgKufhCx1fENa-U6bKonAW_-O2tGiUsGuTQmYzLGxSYyGLXoPT6mC1TMAoq5POJxE_u5K8tEd1KiVKJ6c9-iISTCTxNRqgLeLk6OBQo3v_x_xNnjgiCB4Gm5OwfOGd9sljfIpnMq0DbRJremGsF2MW8igbYoHO_NryX6irr13R8kxQL1PF0LQc__A0fYLom32FKnK6y98WRX6A23dkHMMiDtpngNOodGwvORQtp9YNLp6oRZ_3WpdY9v6tmuPqEDPWB7SsZ_RskuzLPK2MMkDb8BhTsVYS2LbjeWHpaVAWD-rAo3ZUQdkWaHQ1q3LECcIEBLPn2dx0cKOnDrj2Fee-kmhCKxKWFkrWFDLsiwZWwsZ5c5lxufsJmOzFihGcPkvfKQ6Yxlu2K_RF-Ya3jSJ14pKnzn2OM5GiWMxjTuE541Xd0opX9KAbMZq3rgaCVHNM7tmCOJmkKXtkwSBTYL9znHhCCDcQ1mXQ5FUGaWR_hR7KWr5P97V5tOAFv01yt8InRLt2h2jY_oX3rcUpVp4MLP-UXsWAHmUJ2uX63IXFBXu58hq5Li7puqFpLyLUh-2NpVGaYGTGzSjw6FVMxqEhk3l2lYVLc08SBks4hDxV0x8U9r0l7LsxETp0Yn43sL-ijP0rjGqasLF3v3U8Xv8rYwbh9lEnrfl31e0z-gaiTOUAW138x15zG0YBO8ZjUcQR5jSY4uaeV3kv02KqD4GhE1aI4vTsKjduWaGZWo75sa2CA0zNDKpMyBah07I0bszrsqr3qj7g09POzGXfZjeOHaCbdG80GwF5INfCZsDrX3dpES8CkYNXKfDvTJNoFvmTEPXdw8Qk-QEpFeQ-gmmrpAExO5mpTxFHtdnGMnKLaVBm3IHitWxYwuPjIIMrNgq3MyG4a7f_rdH7b90qwzInD69w3VFwY8Fh6kPKsY_goFJL5_0iL_dXta7x94Gw5W_seMxCEKHt32of2IbtgpfUtRQfw1jCyg_Ep_z-7ECT7mmiGfvRo1XBORFsQo-wh8K0M8ZfPFeFbsXNSrt3LhnKFJVHc07fuarzF79gOC3bo8dd8KGenIKUf0JYW9gcdB7P8MJy6bsiFMYLbJ1mwGYeWyWTolJJwsTvmGVaTGPWqEFStk8BLmdzLI4Js1bCMBzRjAUtJX3t9cw0HkDvDJfjxUZLhghzK1LdKeYnw0BfDmN-ICiMnQVDF8r3eXCcZhd6uo5JR4c4gY0ppgHvQvxm6sB5so4YwnAlRMn0sTG8FDl6Bc7ZBO5ghMFo2Byr_UjkU_W86_JWZopRu3YTcBSMRIdYXS5cgHHSyLJYlycr29QSsslbCSYtCHRAT6AVaetMFxke11aeC80MrCFj70BW8ItRKcA5HxCEEGpNjRJPGuyI09gXepjAZElZTEsm5GgDNdsVEZaipbnGFgJyRBWjVlOGsRaiQcRr8KkDGZp0Y7S8_rD1QBbhyaBWv4tTxb3F1OkqGj4LBXgq-Tdz6HdeSU0Z3wAEErWG4R9v-FAPjh69BqwGTo_mXlM2_qsUlyhGo6Teob8NN3a3cRD4YTz1xZN5mMmTDc4z9DlzqeFOnlG-WLeGt9I1iE8v59BXH8Rj9GjgBEcj8xAuiG00_CrN0c7asnLccftt5bUfAF8hKC_IgE4Vw-8q3dhAXtJbWQYE_jW2DQ6KhxwNLfxDbODFG2ID0cdmPqZkk_Wc3131bByE0m0XghRCwLwpxHFfgRM-iSp9MxTVrhIyeUmivnKU-DnT2Co7E0q76GlZOCYahy9ASjIxF8t8kl0Noc8OVBK-brwQubTAmQHjlVh25eYTgWW9H8X9s22owASK_1JEt9TEFs-Fd7xD-GYt20POsI-Y2AZhl1f7ZqG0kFSuiAA_NutGR0ogTKN0JjSHj17o1vUkYv3XS6FqXX_xYzF4yuq0l5krhvhfl1mE2XlZBocoviW9s2ROyBva_8ht6PP-AAsqVYO3t84EPtKXmTLwmxSP2t_-C6ozo678Nvc1MuyQ5aow0Mso1MUF5_ucMid4pf7QE3QE_v5NuEgB7tarsp9_4IEtSZhRCUS4euqXs93EK4BW10NE4nMpuNT0fd-bOpK77nLs5QaUB2Z-EsiivTjtLwDPftvI4yCPVXkBupP-yNk0F52gWWRHqAILkkbHa4iszkTNDCjZRgmS23SfeGz4ZO0uKaJJmYmW8BxUBX0FJ4ZjN8nt2DUOAWoA5iHh_sO1SD_EBNS1grT0w147I1y1iyZ2pqtCSEdawSbypgkVItvR1k3UoTXzHJ3Fp5eX_K26EuC0PXn-czsa-XiSVdLAncz3LiORq15oSERRU2aTpP0XV-pzyi4cLpHyorMm--dRhdq2F27_sGJ7aEVQU-6CMmI-iAfNK32dNVYDdUFORLD1UNJe_vWbDHvwQF4re0qhcs0Nqh-oxBx_PsBaAeI5ehnurnTT8fGwoVDeXB5gWwwavQW_E3F5COiJnWiobIw46KsiH_g-L2xJp3XTt61-llbULUr5BwzJ7SvFPsM3-KQlRneBOaJVbN69_NFb_ebmJchg8akyLIWbf5KjxcEIKeEl_EKYs3hgJh_PGJRRuZRtJG7zrSX90I7gyxse32vVq2SNH1d7eze4yAzSs4EuelN4NPAuVJyx7McsvIXmd4xiLByZBO8MP8JUyQ-Mf3hEPDHcZpcjHZeSjBSXYak-laFPEt3797cAWI7fThvM80FLA96GSPbAuhJbDhZbofUqXbKbCJFZcdgkLqmCziWGGdJD1RqymLLQ1fOzTFC-DFKsqp7Vl_7nw64a2npnRuS2nauW-zy33CahKiOfM68eMwyJ4-nddPXKycJn_BJJS-cVHIKVGJpbnzz2H8osiPp7vNX-3iskwefo8EltzpmMTMMnCE9YPIbr1ISsrG_Y8cAXxo2lxgckZsNrI5tIBt5XuqilyOnndqFmfILXNJQSVs_K2OffqygOfiCFR_NWcNg7BF2NNxPZjvof_yWwZlVgfw2jI1ikLLfTOGLaIyYTTwX7HtqlpD2205I-nBWVH9ciRC3MijHmn4TqyAnwhQOfjKDXMEGnO8q-2JJ3gHaBkmdL558WIC5q3kPvzg7V6VBJ39s68fQv-l6sHf0B5st4WgFC1p9-iyrLN5GEc3FfKg7O5cZBmPLAsVuBLQQsjjqR43Fl2VGYllamhJ0mdR_sS1CPEeiNJdYfZ2ZELWg5PDAuWGyLxjzm6ZwTf9pbmhruOKi_reHtwPNLp22BVmTEu5ytIqIfJN9m9hNmMOdpLSlK69kfejK9NAomWR4UXrZXqDkdzuDWtlWuSY73xdOvIqK_GQHFMhJeVjfrDT-FeAYUTKfA_nLpvyZ0XSaPR3RURM6pJneUahxCx_gcUyqghPoedJyBEYEAaeK-bkeBlc5Zb1XNVfcTRn4Jo5rs_OfH-ep2U8FiboeIz98EpQEFrN6u5NO6vZqQVmQsmOdyilJuJkSYhaIMZuHvQgYp04dvBPbrmUt5RsjU3YOUkP-slE9Awz4942UEoxG2Ds5ux1QFt6QrgjJv7JUjP4e028DwaZvLGWAZJGPibAvCsQYXdvdblq64ZrQNQlrPaATuVXhreDLPMANzCzuJSBeb0rIzNdOzgjsmPriAp2v9oSoafCZL-aaDpVCaHCFFgIGivcCUX6mUnJbLKna7GpJSAME9YmoOcs1OZeG42i_Ueih00r04VSJCsJ54fG2O5dptn7u6Vd90-QSAdBk-865UNSwDen_XNu_i1Rf77qAr7Wvx9bCCNsr2Sh_mbJR2csP_Y-Kar9ZzBRCELqbRKHx2x8VjTHmcA0fGv7jlNxm1TZ1URftgYUiz-10VejboDCL2q1D6GnOnmN41t2CAvAUoPSL1_mu9-YfwGlvHJxBw6TmSXXY-dbKXTq19t-uVtVTJXfRQDQrJKQYMjZ8M8ziNtluH9o7zi0KvjZjQUHkD-xn2o4833xp8lLiaECGKaoh6W1dkU65jIqXsq-lczwTitKEl02nMdoB6qPdDVCAovzVFgXZmehfiX3UR4dXGvXutXG2HQPSbpB-yHMZg41ty-Qh_pA9irNGv0K5L-2b-nklcLjbNjcYCtTJAIMcmsDRBGqeIiwGfLu0NQLqbH6SHSmi2cqDcVsIzAI1ipAbG6sKBdqBqMxB4kC7acFCTEB9fPMqOZWBu_auc11TV_sLSXvwhUpdv4OjfWhZ3O21qmNIuyqR7VjNT_KoJq3I4LkuLDFeXUfquWJ8mLYLahcxh4WiihYl-vskVA44HoIHrxoK4NgMUBENJ7w0AW9eKcPSmznyjlJ0mRiQ5_eXHRC9LU2oA_hgYX0RClTEL8PhgRoL0jUsv0P5IUkbIl3DS_GF7qj4YmZZ4zKfYdUHj7cLxaMMi7zoyxe80M63uwy0eC-2QgrOiV5YER1SM-Es0X-J43bdFPkZPRFkB5eGe4l1SRIrLK3wlAiMW-xEg2CbLaQsMYNSEeBQwltbFFkGhww93efusX0VTMcRNA0EBYcbdnthoMD2XsVR0dKFdxcjk9Lqremoy5Di0isn9Gitlq629DnmAyh7UJmUiHjQQxaHPHYTz3zd32KNT3e3KhzPcVK6cjnaeYwLZSy7SwfxpJS6DdOVCT2F1XzX-pO0FjCgTuwpH_bAvAyup80V2p0DCZKQ_b04jY31pEvm7zsnIibKYOvs4aH6x1D9Z69dQc5uLxw20N8dOxtJI89vMoV3__ClyvJ0u1gZfdCJ2vIZwDnwgEixFgByAxFIe_Ph_L0K7BtGvcgjnoxZYHUHNix-Zf0mbfI_WdmV_CkIL-U2DU-De4hfOGvWNfRAFblwQfd2PFnh5nQrpAZ6F3A78m7RJdFjXs6ZpeZdWX_sA2eobDXrZHQtMDW7HZHe0vkO-3LHGC6CM4NcsKOIwXsdXKCDnBOj7UJfp24Un6N_ITlV0Yuxm67-xDcynvcqrYkqoodlLAYJd0hbJro29dVjpZLpn10M7TTErZz0tCUm8b_l99sApe2Lst-a-OARY9-qfydqv7Inpr_0oN4wDC__taENGRWi3BbmnSyXyuY059MuVno_dLNC9tK3Ilz4rChJTfxFcaPswN4wxcFaj-dShOFDLcu_rrNDOL2MlPMWBdox0o4fJCusMQxR1Up5LcCOcYbym7k-G10YxGalIr_az91P_ULuvuQN2RF1Sjr5fNkORBiF0sJ8pvD5E-nTiRs4uAo3Uf0WkOm8zQ-cso-nELx2dB7aufYolPFrgog93IW64KuOEu4V4pqU8QcetmKZqchLyr35PgR6u0lWruaejqloSaXGqAxR7BDvk2pvRN-WlGcx1j3Ko6c6cXiPPIpPJVInay35xUpdnkpiJrT44ukyIEWN_LaI3uZ63HtJLZF_BTaWD4hmGsn9iO44wBWuykH2nd8a6O0dc4RaE0vYitF7f6ai_eFkVMg8waEwcEvdc-Ema5Q2FeapGUmMTin6l_qHVOxPx8GSzNonn5gqxfIUzV6XlR5FRnbEjSG1l6r-1VvI6ox8Qg9dQDegZLSWPcnJzApt2AodtJXYAllbZ5n-EPJPb-auup9LVzPMwj23lTzufQTHhAJoExdVApdi8V5KcNkusug37WVQlucdIHBLQoKZF3tZhcB9k-H3zuEN8nP6qZV0M7La0JD2owNh5pVYRplXIDbFrApzwpoqUp8QIMbEy9WbiEXyetdpW0zoPnxvhE0xLzdOw5HN2FRB7-G-eFxpr3X4K5NwrO9PbkhafqWISG9K4s9m93Y9yjnhmLg6fvNZ7JZJ90gIJdKZkxFIY25_X9BXJUr_ReaBl602WoRvrD8y2vlDXNv97qvZnH7njP7u6MDsSODunUzTN9ZPSMTrENMzjPBH7oYmdiDkd-wajA2xl7738DRC59c-eY_ZJk9fow6Z3N5h19jpPBMF4yEyhICSyiPoEf9cN4NOQju9AyONkqeo0SVDNN8TML5Frmq3ilhl6ESuOxGMx0kPXXe5kHi_RlLEn7K8rqpEK7DMmT6--oDJr2Eur5iZwWkbnQgclje52P8OOZuoXoyYjAak4qwV9fAkpddUNDnKqPKBqggLQ7BXEyPrnUGBj2a92SaVZF9ZYlBLF1qmrzm8gAq6UGXXdI3Gf1w8G7Eo_OnoU07RwMDGmsPdQv8V1tAVvNyLa8RX_RWzFmXzHbJo6k1b7JSzfrUf48iP0yZLoNVcfxdF2p2C2x5fAaZcJfFJiOqIQW2kFGpoA1A43UlUym8lxuAq6zFu4qPq0HpSfogJFftLmdvwprbfB84X3Xj0Ve6ASUoBydVCidmGrTW4zZmluzgynL01wb9ZEPMpvPxqg0hzW-Y4Aqzf6vB_2xi0C0pWP98kU-0Va79pwluvzmUwDTEEmOJr6zFz6tjXKMQCRV1oXBx2xdqH9HNJhU2cpHz5rTxrNxuZLxdVHny0zIk8XPQ7fhrcyMRGc6QqEwmq94yfqT1KXfhWb5UIH-F_JpIE71OnihMjguMXq6ml1on6A9R7rqh4nFb9hH9tBLJ67ijAFSaSLHtCkYXl1wv1KaKT9LilEsvIJp87kNl7MWW4IF2gSiuhKXGqR24P-hDaBMnPu_5PUmrTKjEcilJpGs8ovtf_wdOxEQsaTxgWMzm7Yuqo4VS5L1daJCSAaiMFRumvtWDu23Hr5jS090PGLyLTkK9IuqsMuxlEwxppDEzbdczc_OQU7cHmNqXKgyQaUk_qvqEPF0av0ixoL8m-CKSEs65jpc-a_L9xhVbMXcyh2wJY4G_awOsJcNrQwwlFYHwW_89yoZMx-4BhLfTfj-qMVgNXoU6wteP_ywRv4Peg9S-GcdYtfQoRPeiDm1u32Zd7ROgZn2fkihnC2MnZdBEy31ST3LBMhVq8da_w38UfIZT4lZS2yZy8J0f5SqHYkCMg90_5AKoNSrwoDbKzEdwAzfsXw9IrBbYqWbHRq6gmkb_n-P7ag0zqE1CCRIzunCl7YDx9mxRUX43TAAAeabQtXgnHl5HS1h74_4fHvvwHsZYwUxwqPpy6GK8HLZbW117rrxTN2BMagmL4WJJH0UFcGVk5PVC34Rcc8rzLUkVVeRx6quiT_iyxkUt6aAUg3egHJS7x73sB6kYhHHcdh5cXTe05QaJT7mkxB2gXwPV3u8DRqHzhcKNMpVQ8uRExfCqduds4QpCW9n4naBrGDBQ1io4loBPUqrif-8M4BYfsfyxtXPO1Fl2a-7gUUsT8pK6-pRPRwBChweKjd8cqfw2e08ewnpPG93OLorFkR6LqRO4gp-fKT5_s9XOClTBiqXKvnVMtDi3NikVaJvjt5Bl7JA28bzwtjcM1vwXfSiiq7smkdVmXgBdDiRDVideLLmDFL2Y3l_bU37rUfas3G0Q_SnbFijXVAdUByZLiGPO9cxbfWN0uXVaRy4MmB3XY5MiqC12jHNDlkVDfgPkSa0ONj1YUcUSu8yvi5eil5pjFrXN8llcuhAI9A-6g4ZM8GnJcte5qCAgSQxfHlISU9b7UeLemwu6E8kqM7jNsH-APkuqA3REJU2XJR9LvNbYZ1-JZ0aKtu-WScmJmffZl6ur8t0Lf_MmYAMPvm44q7oUdwLHH55UGHytjCdhYwspjM-6FfQ7Y5GcSdNGGhiWVB7tz7_9C6bdTdM7dnZzFfq_OAIaCS_RRXe_dSSdnAYQQbLltCil3P10GZgc4V5J7tKJ-rmlNO7QT0kPcj6N1S50EeFTEoYk1-8aQmsBR0u0QFdDEIxIO7BEQTs9lVgZnComaqRZF4x0NVVeEkL5eHeBdN_Vz5MvOSHScFhk6Z4XTatxWBlM7Huv8Yd0b59gbCqBJDmTkUBgGAoKUN2NrM_3E-wJbisBZ-vDH64c4WNGCCFp0Vy8h_n-J5Fa-cI_bVNa1eu1gutFw-HLvnxR3JzD1_vClIFyq-4VhKgM6TeyN_grpa-IzHoSZpjdOHQtpxCBH4ipeEUNIoPk8nFi0XqpSYinLKNhfLKodTrAFgEBlL39YH4_j8eFjmnEAMNpenTuPKFkX9qSvvnl7BEx9O_3QHnU5CWXyKHsJHDpsgKAgT5uyDgJDI2OSooiAAHTHNQv2mIzFgcPdqWLkf6tyIjtikCO5CTAEOPgyBdPqy88EBEevyMHI1fdlGLGEzDe6SrSnKl33LpBj-GGQ097WNi7eOYtcue9VAKT66s8u7wrMD2d7YmhUzL-NEhM0YrEtFwEHXPaK5yzRODc5PDOKkoWzRWT3XXWifCfhnwed7psgXAehmjhX-Ioi_ziJAlznz0a-yC-XFPDxbD1KBj58kEromHzOa_f-INa3x_q_Ld4yQkEp_lAylyhL68ShTMwe7ErCdvN6pNcr6oUSh8xfpIa7lJL9lCeXlTN4xE57PFZJPNphqEvYEN3YWiTOy8a23dakQiG0UzX_fnq9yQ5KJX-yCcHFs2ypaJ0o884FxMaLHWGtJIjX19Fl08NuulJz3p4fxsX6kzS8TLILiRSmoaycPeaESKKki3BWU0nXeQPAvUOE-I62qZYMwOyXjSrB7Z4eu7YSSwKxvR_Si9aq-JXS3nVn4f9DhIDVkbCiaKWaqhLJxdae-Azk5vwcjqLvDNDj3P2ZxaGH4QGLSM4fg-9MwTc2UbdWUjleM1UfquY61Up1fl2x8bEC3OjfjIXA_GoqvnaKbdfOGDbTlM3w-mKO92aELRwxlSlq-lf6PfaGtMa56Nb3C0aic9NHjmA3yQAF4PdDGDiulq1wolRUwyBzgq99sj85e9_MRcZ3KGzmA9ZwLNd1DNqB4Yfk44sbTHlfTvFRSWSsMQO2iZ1ZWbp6XuKB3hUryqxsfFwohePuWxFrFqHOTYyReEBJSmZzbaVhTvnaf2jHc8WJtV65mzqOh4d6U8aGkFhO6zs0n_0QGDcHziLrVvQpghY_AZ6xgEXwFsDZlznAsclZIcxYq0uF9AYvHaAlfuFDMhfCa68SmBvGUDH2a2hMto9MzOaL8gaV7yxvqycLhoVKHDzIWPaxjiQBnv-tVVtQGUVdoDNAL7XU0aKbuH1x1gnYs_SKkC-aA-gKL2On9jhj5Bmhe_PHSvFOGnAT7VffgIovGjceWnzdZRgw4tW0UWzjxZzJfpHi47QvN3pu5bK3ZW9ANFXCTk5IpUV_S44mYb_35hNNKemO35c82AwKkBuM8oxmXpA5MRnMqql7pkm99JpM23tgYMs9DWSzRcJja1nBAn6j1EuQfh3yS-DMhNmE8PehF6JANJrU6IdluPHPmDd_KDaPPfDnLJYNl1kGoVt36vbm1XlXB4Lzo7FJKLhvnUZNK9YIRz5ggG4luN5oXhaOL74cdWUbmNIHJLk-BYMYnWKXMpcoocj-AfXBxHjCWcIxf_ZPR0I_DWUTqEuoo0I7eEsaSWD6rbHX0foGNPp4h24oDiJM1OzS6vx7VRkPc0J6jPiKepAxYybbb5hGs3YAfqD7jdX6b0FLeo2TWoh6nZfEozY8gExX4VUeomZ_WkYFwAgaBhNjAibLK2KDp-pya6usI27Ew579BwscPOjxFJzF9wcAFY6TtVg4YtYgfzXXldEdeTFet9kLFHiyL40KJqwXN2MTBL5yCi5mtqYui2tKAXlO12JcM6RpZ3tnDJyPRic8BzV3wzvr5MR8klHNysSBzIrt4p4nMD_OQQ_P5ouw50wtmsqdOXCOFq4S7bJiGTSOV4tTCK23kx0FXJQ9cqPCKPo_SvVVPV8hRzYGFTjWUzD-HBa4LgkEQm4z2EiVUBkg8A1DxWjipHmZZDY49ZoAawW9er62nd8TghJjb3ckEdtbEcVwlID1up71YS0tL8KSN6MRPzVWNuzu3PK0PSyXPPBYjIhu1aoJM6r6oZr0dYx2WMl2CRJnjajpL7wosg_-VdUeYkDDIdH6CATX8c4ZLGWV9ig1FmUuOzt9iobTZjdS86p8xx4DFwxaV9EqB0TfzZxgMbSNreOQ3XyhxPKZPc_8scyG7AD9i-fnWel4QnMu55CIPcjJb4CDAPlfYvnfR9vyV5AUwE88KrI3Q15ApcybnI1x68iz8I__1qV3DKHQ1dDlqFvKOLw3WxqMKiwnFmt-oPV4I5PyNjfqiUksx6L0wbqII9njnlITTL1lSNn_WmsULqyRLY5JnY0KzVmbWna2Ces07vIhsKi6zJRx6fNkgOI5FAsftncJPK0bgNAlkjPr2tIrIxPIpf22rdtFN46NfC8WqGMm9gwBorBEPUsFENfxsYdxLLF2rVmFEHcfPVPzOhTpCxnj6XsISX6zAbJmGBEsfS2Kpiz4dQ1WQwTWgrZHR3JyAG_f3sY2oxcBiPit_119ZINW4XzayK0pXM_Q1ZcJvcUeUNN8vwbu_tehdRT3Ng_rU18uqokNiRuGGyV1RbyJJ89ocGDihDgVkHtkNDB_fJE4ii7AzNGNWFJXZ1z5aiG5tDioYUupk97AkrIQstAgqf3UlWOlliykJzabr9GzRWeDAcETj1lc1iFRNW0bGSEcd0kZN_CZQPr0qtxGVAmP3P1xN_Ihu_t9wzZ71ea6KNnbJcGt9sRp93T6o0P67zDiqQ7k57CrWE-GjxVHKuDVC6q0JtUeNnZb3nAQYV7Eiu5FS62rkQZ7KO03fRazIqUqzz3r1a3jg-eloZsLg12XRJt72d0uuQ8rjamtSOYi2MF8y_4j8102tuuhPfeKCm5uG8nb5x4p0CYLRc9iX_z996pAC2llnPAh61wgc_oSOLpnrR489F5nRudy-TQJFpEV6TUAWDyNtFWzO1lIQVYIMQRLYzrJB5vaWvphkGmVSXIU5ybKXMs0f2z4TCnaIMsWHdkS7f-Uj2VABaR2UN3aW-DX4A7az6Z8
13 changes: 13 additions & 0 deletions backend/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
FROM python:3.11-slim

WORKDIR /app

# System deps for psycopg2-binary are bundled, but keep image lean.
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY . .

EXPOSE 8000

CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
1 change: 1 addition & 0 deletions backend/api/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""API package for the Migration Evaluation Platform (MEP)."""
1 change: 1 addition & 0 deletions backend/api/routes/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""API route modules for the Migration Evaluation Platform (MEP)."""
Loading