mirror of
https://github.com/aaronpo97/the-biergarten-app.git
synced 2026-10-14 17:54:42 +00:00
* Integrate Spectre.Console into seed application, use async data loading * Replace stored-procedure repositories with Dapper-based repositories Removes the USP_* stored procedures for Auth, Location, and Brewery data access in favour of services built with Dapper. Adds a new Features.Locations slice and optimistic concurrency support for the Brewery slice. * Add new documentation for Dapper migration/database schema * Update FluentAssertions to most recent open source ver * Update XML doc comment in backend projects * Modify brewery location dto to include denormalized data * - Updated column names from 'Timer' to 'RowVersion' in schema.sql for - Introduced new BeerPost entity and updated BreweryPost and BreweryPostLocation entities to use 'RowVersion' for concurrency. - Modified UserAccount, UserCredential, UserVerification, City, StateProvince, and Country entities to use 'RowVersion' instead of 'Timer'. - Updated tests and command handlers to reflect changes in concurrency token from 'Timer' to 'RowVersion'. - Adjusted BreweryDto and BreweryDtoMapper to include 'RowVersion' and updated mapping logic accordingly. - Ensured all repository methods and interfaces are aligned with the new concurrency handling approach. * updates * Add BeerStyle entity and related properties; refactor BreweryDto to remove BeerPosts * Fix Api.Specs test failures: stale Timer column refs and missing test.user fixture * Remove repository tests, usages of registration dto used in repo * archive old stored procs/functions * update stale docs * Add instructions for generating cryptographically secure base64 secrets on macOS/Linux and Windows
1 line
68 KiB
XML
1 line
68 KiB
XML
<?plantuml 1.2026.2?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentStyleType="text/css" data-diagram-type="DESCRIPTION" height="1259px" preserveAspectRatio="none" style="width:4609px;height:1259px;background:#FFFFFF;" version="1.1" viewBox="0 0 4609 1259" width="4609px" zoomAndPan="magnify"><title>Docker Deployment Architecture</title><defs/><g><g class="title" data-source-line="6"><text fill="#000000" font-family="Arial" font-size="22" font-weight="bold" lengthAdjust="spacing" textLength="342.3213" x="2128.8394" y="35.6357">Docker Deployment Architecture</text></g><!--cluster Development Environment\n(docker-compose.dev.yaml)--><g class="cluster" data-qualified-name="Development Environment.n.docker-compose.dev.yaml." data-source-line="12" id="ent0004"><path d="M13.5,388.7879 L199.6719,388.7879 A3.75,3.75 0 0 1 202.1719,391.2879 L209.1719,426.9851 L1778.5,426.9851 A2.5,2.5 0 0 1 1781,429.4851 L1781,1250.1079 A2.5,2.5 0 0 1 1778.5,1252.6079 L13.5,1252.6079 A2.5,2.5 0 0 1 11,1250.1079 L11,391.2879 A2.5,2.5 0 0 1 13.5,388.7879" fill="#E3F2FD" style="stroke:#000000;stroke-width:1;"/><line style="stroke:#000000;stroke-width:1;" x1="11" x2="209.1719" y1="426.9851" y2="426.9851"/><text fill="#000000" font-family="Arial" font-size="14" font-weight="bold" lengthAdjust="spacing" textLength="177.3652" x="18.9033" y="403.9197">Development Environment</text><text fill="#000000" font-family="Arial" font-size="14" font-weight="bold" lengthAdjust="spacing" textLength="185.1719" x="15" y="420.0183">(docker-compose.dev.yaml)</text></g><!--cluster DevDB--><g class="cluster" data-qualified-name="Development Environment.n.docker-compose.dev.yaml..DevDB" data-source-line="14" id="ent0005"><polygon fill="#FFFFFF" points="1093,892.0679,1103,882.0679,1471,882.0679,1471,1210.6079,1461,1220.6079,1093,1220.6079,1093,892.0679" style="stroke:#000000;stroke-width:1;"/><line style="stroke:#000000;stroke-width:1;" x1="1461" x2="1471" y1="892.0679" y2="882.0679"/><line style="stroke:#000000;stroke-width:1;" x1="1093" x2="1461" y1="892.0679" y2="892.0679"/><line style="stroke:#000000;stroke-width:1;" x1="1461" x2="1461" y1="892.0679" y2="1220.6079"/><text fill="#000000" font-family="Arial" font-size="14" font-weight="bold" lengthAdjust="spacing" textLength="76.2617" x="1239.8691" y="908.1997">SQL Server</text><text fill="#000000" font-family="Arial" font-size="14" font-weight="bold" lengthAdjust="spacing" textLength="302.6816" x="1126.6592" y="924.2983">(mcr.microsoft.com/mssql/server:2022-latest)</text></g><!--cluster DevDBInner--><g class="cluster" data-qualified-name="Development Environment.n.docker-compose.dev.yaml..DevDB.DevDBInner" data-source-line="15" id="ent0006"><path d="M1124,1013.3879 C1124,1003.3879 1169,1003.3879 1169,1003.3879 C1169,1003.3879 1214,1003.3879 1214,1013.3879 L1214,1186.6079 C1214,1196.6079 1169,1196.6079 1169,1196.6079 C1169,1196.6079 1124,1196.6079 1124,1186.6079 L1124,1013.3879" fill="#FFFFFF" style="stroke:#000000;stroke-width:1;"/><path d="M1124,1013.3879 C1124,1023.3879 1169,1023.3879 1169,1023.3879 C1169,1023.3879 1214,1023.3879 1214,1013.3879" fill="none" style="stroke:#000000;stroke-width:1;"/><text fill="#000000" font-family="Arial" font-size="14" font-weight="bold" lengthAdjust="spacing" textLength="70.0205" x="1133.9897" y="1038.5197">Biergarten</text><text fill="#000000" font-family="Arial" font-size="14" font-weight="bold" lengthAdjust="spacing" textLength="62.2549" x="1137.8726" y="1054.6183">Database</text></g><!--cluster DevAPI--><g class="cluster" data-qualified-name="Development Environment.n.docker-compose.dev.yaml..DevAPI" data-source-line="29" id="ent0011"><polygon fill="#FFFFFF" points="157.5,483.7879,167.5,473.7879,781,473.7879,781,840.0679,771,850.0679,157.5,850.0679,157.5,483.7879" style="stroke:#000000;stroke-width:1;"/><line style="stroke:#000000;stroke-width:1;" x1="771" x2="781" y1="483.7879" y2="473.7879"/><line style="stroke:#000000;stroke-width:1;" x1="157.5" x2="771" y1="483.7879" y2="483.7879"/><line style="stroke:#000000;stroke-width:1;" x1="771" x2="771" y1="483.7879" y2="850.0679"/><text fill="#000000" font-family="Arial" font-size="14" font-weight="bold" lengthAdjust="spacing" textLength="92.5654" x="418.9673" y="499.9197">API Container</text><text fill="#000000" font-family="Arial" font-size="14" font-weight="bold" lengthAdjust="spacing" textLength="68.4482" x="431.0259" y="516.0183">(API.Core)</text></g><!--cluster DevMig--><g class="cluster" data-qualified-name="Development Environment.n.docker-compose.dev.yaml..DevMig" data-source-line="48" id="ent0018"><polygon fill="#FFFFFF" points="813,669.2779,823,659.2779,1053,659.2779,1053,1052.2879,1043,1062.2879,813,1062.2879,813,669.2779" style="stroke:#000000;stroke-width:1;"/><line style="stroke:#000000;stroke-width:1;" x1="1043" x2="1053" y1="669.2779" y2="659.2779"/><line style="stroke:#000000;stroke-width:1;" x1="813" x2="1043" y1="669.2779" y2="669.2779"/><line style="stroke:#000000;stroke-width:1;" x1="1043" x2="1043" y1="669.2779" y2="1062.2879"/><text fill="#000000" font-family="Arial" font-size="14" font-weight="bold" lengthAdjust="spacing" textLength="70.7793" x="893.6104" y="685.4097">Migrations</text><text fill="#000000" font-family="Arial" font-size="14" font-weight="bold" lengthAdjust="spacing" textLength="69.2139" x="894.3931" y="701.5083">(run-once)</text></g><!--cluster DevSeed--><g class="cluster" data-qualified-name="Development Environment.n.docker-compose.dev.yaml..DevSeed" data-source-line="58" id="ent0023"><polygon fill="#FFFFFF" points="1511,669.2779,1521,659.2779,1749,659.2779,1749,1059.7579,1739,1069.7579,1511,1069.7579,1511,669.2779" style="stroke:#000000;stroke-width:1;"/><line style="stroke:#000000;stroke-width:1;" x1="1739" x2="1749" y1="669.2779" y2="659.2779"/><line style="stroke:#000000;stroke-width:1;" x1="1511" x2="1739" y1="669.2779" y2="669.2779"/><line style="stroke:#000000;stroke-width:1;" x1="1739" x2="1739" y1="669.2779" y2="1069.7579"/><text fill="#000000" font-family="Arial" font-size="14" font-weight="bold" lengthAdjust="spacing" textLength="33.4619" x="1609.269" y="685.4097">Seed</text><text fill="#000000" font-family="Arial" font-size="14" font-weight="bold" lengthAdjust="spacing" textLength="69.2139" x="1591.3931" y="701.5083">(run-once)</text></g><!--cluster Test Environment\n(docker-compose.test.yaml)--><g class="cluster" data-qualified-name="Test Environment.n.docker-compose.test.yaml." data-source-line="71" id="ent0028"><path d="M2146.5,57.2979 L2333.4443,57.2979 A3.75,3.75 0 0 1 2335.9443,59.7979 L2342.9443,95.4951 L3611.5,95.4951 A2.5,2.5 0 0 1 3614,97.9951 L3614,1097.8879 A2.5,2.5 0 0 1 3611.5,1100.3879 L2146.5,1100.3879 A2.5,2.5 0 0 1 2144,1097.8879 L2144,59.7979 A2.5,2.5 0 0 1 2146.5,57.2979" fill="#FFF3E0" style="stroke:#000000;stroke-width:1;"/><line style="stroke:#000000;stroke-width:1;" x1="2144" x2="2342.9443" y1="95.4951" y2="95.4951"/><text fill="#000000" font-family="Arial" font-size="14" font-weight="bold" lengthAdjust="spacing" textLength="118.2412" x="2181.8516" y="72.4297">Test Environment</text><text fill="#000000" font-family="Arial" font-size="14" font-weight="bold" lengthAdjust="spacing" textLength="185.9443" x="2148" y="88.5283">(docker-compose.test.yaml)</text></g><!--cluster TestDB--><g class="cluster" data-qualified-name="Test Environment.n.docker-compose.test.yaml..TestDB" data-source-line="73" id="ent0029"><polygon fill="#FFFFFF" points="2762,642.4779,2772,632.4779,3150,632.4779,3150,1058.3879,3140,1068.3879,2762,1068.3879,2762,642.4779" style="stroke:#000000;stroke-width:1;"/><line style="stroke:#000000;stroke-width:1;" x1="3140" x2="3150" y1="642.4779" y2="632.4779"/><line style="stroke:#000000;stroke-width:1;" x1="2762" x2="3140" y1="642.4779" y2="642.4779"/><line style="stroke:#000000;stroke-width:1;" x1="3140" x2="3140" y1="642.4779" y2="1068.3879"/><text fill="#000000" font-family="Arial" font-size="14" font-weight="bold" lengthAdjust="spacing" textLength="76.2617" x="2913.8691" y="658.6097">SQL Server</text><text fill="#000000" font-family="Arial" font-size="14" font-weight="bold" lengthAdjust="spacing" textLength="122.917" x="2890.5415" y="674.7083">(isolated instance)</text></g><!--cluster TestDBInner--><g class="cluster" data-qualified-name="Test Environment.n.docker-compose.test.yaml..TestDB.TestDBInner" data-source-line="74" id="ent0030"><path d="M2786,756.3279 C2786,746.3279 2840,746.3279 2840,746.3279 C2840,746.3279 2894,746.3279 2894,756.3279 L2894,1034.3879 C2894,1044.3879 2840,1044.3879 2840,1044.3879 C2840,1044.3879 2786,1044.3879 2786,1034.3879 L2786,756.3279" fill="#FFFFFF" style="stroke:#000000;stroke-width:1;"/><path d="M2786,756.3279 C2786,766.3279 2840,766.3279 2840,766.3279 C2840,766.3279 2894,766.3279 2894,756.3279" fill="none" style="stroke:#000000;stroke-width:1;"/><text fill="#000000" font-family="Arial" font-size="14" font-weight="bold" lengthAdjust="spacing" textLength="70.0205" x="2804.9897" y="781.4597">Biergarten</text><text fill="#000000" font-family="Arial" font-size="14" font-weight="bold" lengthAdjust="spacing" textLength="94.9307" x="2792.5347" y="797.5583">Test Database</text></g><!--cluster TestMig--><g class="cluster" data-qualified-name="Test Environment.n.docker-compose.test.yaml..TestMig" data-source-line="87" id="ent0035"><polygon fill="#FFFFFF" points="2420,396.7379,2430,386.7379,2656,386.7379,2656,510.8379,2646,520.8379,2420,520.8379,2420,396.7379" style="stroke:#000000;stroke-width:1;"/><line style="stroke:#000000;stroke-width:1;" x1="2646" x2="2656" y1="396.7379" y2="386.7379"/><line style="stroke:#000000;stroke-width:1;" x1="2420" x2="2646" y1="396.7379" y2="396.7379"/><line style="stroke:#000000;stroke-width:1;" x1="2646" x2="2646" y1="396.7379" y2="520.8379"/><text fill="#000000" font-family="Arial" font-size="14" font-weight="bold" lengthAdjust="spacing" textLength="70.7793" x="2498.6104" y="412.8697">Migrations</text><text fill="#000000" font-family="Arial" font-size="14" font-weight="bold" lengthAdjust="spacing" textLength="34.2207" x="2516.8896" y="428.9683">(test)</text></g><!--cluster TestSeed--><g class="cluster" data-qualified-name="Test Environment.n.docker-compose.test.yaml..TestSeed" data-source-line="91" id="ent0037"><polygon fill="#FFFFFF" points="2176,134.2979,2186,124.2979,2380,124.2979,2380,515.2079,2370,525.2079,2176,525.2079,2176,134.2979" style="stroke:#000000;stroke-width:1;"/><line style="stroke:#000000;stroke-width:1;" x1="2370" x2="2380" y1="134.2979" y2="124.2979"/><line style="stroke:#000000;stroke-width:1;" x1="2176" x2="2370" y1="134.2979" y2="134.2979"/><line style="stroke:#000000;stroke-width:1;" x1="2370" x2="2370" y1="134.2979" y2="525.2079"/><text fill="#000000" font-family="Arial" font-size="14" font-weight="bold" lengthAdjust="spacing" textLength="33.4619" x="2257.269" y="150.4297">Seed</text><text fill="#000000" font-family="Arial" font-size="14" font-weight="bold" lengthAdjust="spacing" textLength="34.2207" x="2256.8896" y="166.5283">(test)</text></g><!--cluster Specs--><g class="cluster" data-qualified-name="Test Environment.n.docker-compose.test.yaml..Specs" data-source-line="100" id="ent0042"><polygon fill="#FFFFFF" points="3190,354.9879,3200,344.9879,3582,344.9879,3582,552.5779,3572,562.5779,3190,562.5779,3190,354.9879" style="stroke:#000000;stroke-width:1;"/><line style="stroke:#000000;stroke-width:1;" x1="3572" x2="3582" y1="354.9879" y2="344.9879"/><line style="stroke:#000000;stroke-width:1;" x1="3190" x2="3572" y1="354.9879" y2="354.9879"/><line style="stroke:#000000;stroke-width:1;" x1="3572" x2="3572" y1="354.9879" y2="562.5779"/><text fill="#000000" font-family="Arial" font-size="14" font-weight="bold" lengthAdjust="spacing" textLength="68.4756" x="3347.7622" y="371.1197">API.Specs</text><text fill="#000000" font-family="Arial" font-size="14" font-weight="bold" lengthAdjust="spacing" textLength="122.1172" x="3320.9414" y="387.2183">(Integration Tests)</text></g><!--cluster UnitTests--><g class="cluster" data-qualified-name="Test Environment.n.docker-compose.test.yaml..UnitTests" data-source-line="114" id="ent0047"><polygon fill="#FFFFFF" points="2709,325.0979,2719,315.0979,3150,315.0979,3150,582.4779,3140,592.4779,2709,592.4779,2709,325.0979" style="stroke:#000000;stroke-width:1;"/><line style="stroke:#000000;stroke-width:1;" x1="3140" x2="3150" y1="325.0979" y2="315.0979"/><line style="stroke:#000000;stroke-width:1;" x1="2709" x2="3140" y1="325.0979" y2="325.0979"/><line style="stroke:#000000;stroke-width:1;" x1="3140" x2="3140" y1="325.0979" y2="592.4779"/><text fill="#000000" font-family="Arial" font-size="14" font-weight="bold" lengthAdjust="spacing" textLength="62.2275" x="2894.3862" y="341.2297">unit.tests</text><text fill="#000000" font-family="Arial" font-size="14" font-weight="bold" lengthAdjust="spacing" textLength="217.0547" x="2816.9727" y="357.3283">(Features.*.Tests, one container)</text></g><!--cluster Results--><g class="cluster" data-qualified-name="Results" data-source-line="134" id="ent0052"><path d="M3910.5,661.2279 L4032.8311,661.2279 A3.75,3.75 0 0 1 4035.3311,663.7279 L4042.3311,699.4251 L4593.5,699.4251 A2.5,2.5 0 0 1 4596,701.9251 L4596,1067.2579 A2.5,2.5 0 0 1 4593.5,1069.7579 L3910.5,1069.7579 A2.5,2.5 0 0 1 3908,1067.2579 L3908,663.7279 A2.5,2.5 0 0 1 3910.5,661.2279" fill="#FFFFFF" style="stroke:#000000;stroke-width:1;"/><line style="stroke:#000000;stroke-width:1;" x1="3908" x2="4042.3311" y1="699.4251" y2="699.4251"/><text fill="#000000" font-family="Arial" font-size="14" font-weight="bold" lengthAdjust="spacing" textLength="79.3584" x="3932.9863" y="676.3597">test-results/</text><text fill="#000000" font-family="Arial" font-size="14" font-weight="bold" lengthAdjust="spacing" textLength="121.3311" x="3912" y="692.4583">(mounted volume)</text></g><g class="entity" data-qualified-name="Development Environment.n.docker-compose.dev.yaml..DevDB.GMN8" data-source-line="19" id="ent0009"><path d="M1249.9,946.0679 L1249.9,999.6079 L1202.33,1003.6079 L1249.9,1007.6079 L1249.9,1060.709 A0,0 0 0 0 1249.9,1060.709 L1420.1017,1060.709 A0,0 0 0 0 1420.1017,1060.709 L1420.1017,956.0679 L1410.1017,946.0679 L1249.9,946.0679 A0,0 0 0 0 1249.9,946.0679" fill="#FFFFFF" style="stroke:#000000;stroke-width:1;"/><path d="M1410.1017,946.0679 L1410.1017,956.0679 L1420.1017,956.0679 L1410.1017,946.0679" fill="#FFFFFF" style="stroke:#000000;stroke-width:1;"/><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="76.5908" x="1255.9" y="963.2617">Environment:</text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="118.1235" x="1255.9" y="978.2104">- ACCEPT_EULA=Y</text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="131.1235" x="1255.9" y="993.1592">- SA_PASSWORD=***</text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="149.2017" x="1255.9" y="1008.1079">- MSSQL_PID=Developer</text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="3.6118" x="1255.9" y="1023.0566"> </text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="54.1899" x="1255.9" y="1038.0054">Volumes:</text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="121.3989" x="1255.9" y="1052.9541">- biergarten-dev-data</text></g><g class="entity" data-qualified-name="Development Environment.n.docker-compose.dev.yaml..DevDB.DevDBInner.1433" data-source-line="16" id="ent0007"><text fill="#000000" font-family="Arial" font-size="14" lengthAdjust="spacing" textLength="31.1445" x="1180.4277" y="982.4211">1433</text><rect fill="#FFFFFF" height="12" style="stroke:#000000;stroke-width:1.5;" width="12" x="1190" y="997.3879"/></g><!--entity API1--><g class="entity" data-qualified-name="Development Environment.n.docker-compose.dev.yaml..DevAPI.API1" data-source-line="30" id="ent0012"><rect fill="#FFFFFF" height="46.0986" rx="2.5" ry="2.5" style="stroke:#000000;stroke-width:1;" width="153.5996" x="603.2" y="723.2779"/><rect fill="#FFFFFF" height="10" style="stroke:#000000;stroke-width:1;" width="15" x="736.7996" y="728.2779"/><rect fill="#FFFFFF" height="2" style="stroke:#000000;stroke-width:1;" width="4" x="734.7996" y="730.2779"/><rect fill="#FFFFFF" height="2" style="stroke:#000000;stroke-width:1;" width="4" x="734.7996" y="734.2779"/><text fill="#000000" font-family="Arial" font-size="14" lengthAdjust="spacing" textLength="113.5996" x="618.2" y="756.4097">ASP.NET Core 10</text></g><g class="entity" data-qualified-name="Development Environment.n.docker-compose.dev.yaml..DevAPI.DevPort1" data-source-line="31" id="ent0013"><text fill="#000000" font-family="Arial" font-size="14" lengthAdjust="spacing" textLength="115.9443" x="117.5278" y="452.8211">8080:8080 (HTTP)</text><rect fill="#FFFFFF" height="12" style="stroke:#000000;stroke-width:1.5;" width="12" x="169.5" y="467.7879"/></g><g class="entity" data-qualified-name="Development Environment.n.docker-compose.dev.yaml..DevAPI.DevPort2" data-source-line="32" id="ent0014"><text fill="#000000" font-family="Arial" font-size="14" lengthAdjust="spacing" textLength="125.2822" x="242.1889" y="452.8211">8081:8081 (HTTPS)</text><rect fill="#FFFFFF" height="12" style="stroke:#000000;stroke-width:1.5;" width="12" x="298.83" y="467.7879"/></g><g class="entity" data-qualified-name="Development Environment.n.docker-compose.dev.yaml..DevAPI.GMN15" data-source-line="35" id="ent0016"><path d="M262,666.5779 L262,826.0652 A0,0 0 0 0 262,826.0652 L567.9907,826.0652 A0,0 0 0 0 567.9907,826.0652 L567.9907,676.5779 L557.9907,666.5779 L321,666.5779 L317,479.7379 L313,666.5779 L262,666.5779 A0,0 0 0 0 262,666.5779" fill="#FFFFFF" style="stroke:#000000;stroke-width:1;"/><path d="M557.9907,666.5779 L557.9907,676.5779 L567.9907,676.5779 L557.9907,666.5779" fill="#FFFFFF" style="stroke:#000000;stroke-width:1;"/><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="76.5908" x="268" y="683.7717">Environment:</text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="284.9907" x="268" y="698.7204">- ASPNETCORE_ENVIRONMENT=Development</text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="151.3472" x="268" y="713.6692">- DB_SERVER=sql-server</text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="138.3599" x="268" y="728.6179">- DB_NAME=Biergarten</text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="148.8018" x="268" y="743.5666">- DB_USER/PASSWORD</text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="94.6118" x="268" y="758.5154">- JWT_SECRET</text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="146.3008" x="268" y="773.4641">- SMTP_* (10+ variables)</text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="3.6118" x="268" y="788.4128"> </text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="81.6499" x="268" y="803.3615">Health Check:</text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="92.5234" x="268" y="818.3103">/health endpoint</text></g><!--entity Mig1--><g class="entity" data-qualified-name="Development Environment.n.docker-compose.dev.yaml..DevMig.Mig1" data-source-line="49" id="ent0019"><rect fill="#FFFFFF" height="46.0986" rx="2.5" ry="2.5" style="stroke:#000000;stroke-width:1;" width="168.3994" x="840.8" y="723.2779"/><rect fill="#FFFFFF" height="10" style="stroke:#000000;stroke-width:1;" width="15" x="989.1994" y="728.2779"/><rect fill="#FFFFFF" height="2" style="stroke:#000000;stroke-width:1;" width="4" x="987.1994" y="730.2779"/><rect fill="#FFFFFF" height="2" style="stroke:#000000;stroke-width:1;" width="4" x="987.1994" y="734.2779"/><text fill="#000000" font-family="Arial" font-size="14" lengthAdjust="spacing" textLength="128.3994" x="855.8" y="756.4097">Database.Migrations</text></g><g class="entity" data-qualified-name="Development Environment.n.docker-compose.dev.yaml..DevMig.GMN20" data-source-line="51" id="ent0021"><path d="M837.04,968.4879 L837.04,1038.2828 A0,0 0 0 0 837.04,1038.2828 L1020.9653,1038.2828 A0,0 0 0 0 1020.9653,1038.2828 L1020.9653,978.4879 L1010.9653,968.4879 L929,968.4879 L925,769.5879 L921,968.4879 L837.04,968.4879 A0,0 0 0 0 837.04,968.4879" fill="#FFFFFF" style="stroke:#000000;stroke-width:1;"/><path d="M1010.9653,968.4879 L1010.9653,978.4879 L1020.9653,978.4879 L1010.9653,968.4879" fill="#FFFFFF" style="stroke:#000000;stroke-width:1;"/><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="134.3862" x="843.04" y="985.6817">Runs: DbUp migrations</text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="76.5908" x="843.04" y="1000.6304">Environment:</text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="162.9253" x="843.04" y="1015.5792">- CLEAR_DATABASE=false</text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="134.3989" x="843.04" y="1030.5279">Depends on: sql-server</text></g><!--entity Seed1--><g class="entity" data-qualified-name="Development Environment.n.docker-compose.dev.yaml..DevSeed.Seed1" data-source-line="59" id="ent0024"><rect fill="#FFFFFF" height="46.0986" rx="2.5" ry="2.5" style="stroke:#000000;stroke-width:1;" width="136.5166" x="1565.74" y="723.2779"/><rect fill="#FFFFFF" height="10" style="stroke:#000000;stroke-width:1;" width="15" x="1682.2566" y="728.2779"/><rect fill="#FFFFFF" height="2" style="stroke:#000000;stroke-width:1;" width="4" x="1680.2566" y="730.2779"/><rect fill="#FFFFFF" height="2" style="stroke:#000000;stroke-width:1;" width="4" x="1680.2566" y="734.2779"/><text fill="#000000" font-family="Arial" font-size="14" lengthAdjust="spacing" textLength="96.5166" x="1580.74" y="756.4097">Database.Seed</text></g><g class="entity" data-qualified-name="Development Environment.n.docker-compose.dev.yaml..DevSeed.GMN25" data-source-line="61" id="ent0026"><path d="M1542.94,961.0179 L1542.94,1045.7615 A0,0 0 0 0 1542.94,1045.7615 L1725.0562,1045.7615 A0,0 0 0 0 1725.0562,1045.7615 L1725.0562,971.0179 L1715.0562,961.0179 L1638,961.0179 L1634,769.5879 L1630,961.0179 L1542.94,961.0179 A0,0 0 0 0 1542.94,961.0179" fill="#FFFFFF" style="stroke:#000000;stroke-width:1;"/><path d="M1715.0562,961.0179 L1715.0562,971.0179 L1725.0562,971.0179 L1715.0562,961.0179" fill="#FFFFFF" style="stroke:#000000;stroke-width:1;"/><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="49.1309" x="1548.94" y="978.2117">Creates:</text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="89.5972" x="1548.94" y="993.1604">- 100 test users</text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="161.1162" x="1548.94" y="1008.1092">- Location data (US/CA/MX)</text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="106.939" x="1548.94" y="1023.0579">- test.user account</text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="137.2998" x="1548.94" y="1038.0066">Depends on: migrations</text></g><g class="entity" data-qualified-name="Test Environment.n.docker-compose.test.yaml..TestDB.GMN32" data-source-line="78" id="ent0033"><path d="M2935.54,696.4779 L2935.54,742.6079 L2882.23,746.6079 L2935.54,750.6079 L2935.54,796.1702 A0,0 0 0 0 2935.54,796.1702 L3106.4653,796.1702 A0,0 0 0 0 3106.4653,796.1702 L3106.4653,706.4779 L3096.4653,696.4779 L2935.54,696.4779 A0,0 0 0 0 2935.54,696.4779" fill="#FFFFFF" style="stroke:#000000;stroke-width:1;"/><path d="M3096.4653,696.4779 L3096.4653,706.4779 L3106.4653,706.4779 L3096.4653,696.4779" fill="#FFFFFF" style="stroke:#000000;stroke-width:1;"/><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="139.4644" x="2941.54" y="713.6717">Fresh instance each run</text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="149.9253" x="2941.54" y="728.6204">CLEAR_DATABASE=true</text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="3.6118" x="2941.54" y="743.5692"> </text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="54.1899" x="2941.54" y="758.5179">Volumes:</text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="121.3926" x="2941.54" y="773.4666">- biergarten-test-data</text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="70.0845" x="2941.54" y="788.4154">(ephemeral)</text></g><g class="entity" data-qualified-name="Test Environment.n.docker-compose.test.yaml..TestDB.TestDBInner.1434" data-source-line="75" id="ent0031"><text fill="#000000" font-family="Arial" font-size="14" lengthAdjust="spacing" textLength="31.1445" x="2860.4277" y="725.3611">1434</text><rect fill="#FFFFFF" height="12" style="stroke:#000000;stroke-width:1.5;" width="12" x="2870" y="740.3279"/></g><!--entity Database.Migrations--><g class="entity" data-qualified-name="Test Environment.n.docker-compose.test.yaml..TestMig.Database.Migrations" data-source-line="88" id="ent0036"><rect fill="#FFFFFF" height="46.0986" rx="2.5" ry="2.5" style="stroke:#000000;stroke-width:1;" width="168.3994" x="2443.8" y="450.7379"/><rect fill="#FFFFFF" height="10" style="stroke:#000000;stroke-width:1;" width="15" x="2592.1994" y="455.7379"/><rect fill="#FFFFFF" height="2" style="stroke:#000000;stroke-width:1;" width="4" x="2590.1994" y="457.7379"/><rect fill="#FFFFFF" height="2" style="stroke:#000000;stroke-width:1;" width="4" x="2590.1994" y="461.7379"/><text fill="#000000" font-family="Arial" font-size="14" lengthAdjust="spacing" textLength="128.3994" x="2458.8" y="483.8697">Database.Migrations</text></g><!--entity Database.Seed--><g class="entity" data-qualified-name="Test Environment.n.docker-compose.test.yaml..TestSeed.Database.Seed" data-source-line="92" id="ent0038"><rect fill="#FFFFFF" height="46.0986" rx="2.5" ry="2.5" style="stroke:#000000;stroke-width:1;" width="136.5166" x="2199.74" y="188.2979"/><rect fill="#FFFFFF" height="10" style="stroke:#000000;stroke-width:1;" width="15" x="2316.2566" y="193.2979"/><rect fill="#FFFFFF" height="2" style="stroke:#000000;stroke-width:1;" width="4" x="2314.2566" y="195.2979"/><rect fill="#FFFFFF" height="2" style="stroke:#000000;stroke-width:1;" width="4" x="2314.2566" y="199.2979"/><text fill="#000000" font-family="Arial" font-size="14" lengthAdjust="spacing" textLength="96.5166" x="2214.74" y="221.4297">Database.Seed</text></g><g class="entity" data-qualified-name="Test Environment.n.docker-compose.test.yaml..TestSeed.GMN39" data-source-line="94" id="ent0040"><path d="M2212.7,446.3679 L2212.7,501.214 A0,0 0 0 0 2212.7,501.214 L2323.3035,501.214 A0,0 0 0 0 2323.3035,501.214 L2323.3035,456.3679 L2313.3035,446.3679 L2272,446.3679 L2268,234.6379 L2264,446.3679 L2212.7,446.3679 A0,0 0 0 0 2212.7,446.3679" fill="#FFFFFF" style="stroke:#000000;stroke-width:1;"/><path d="M2313.3035,446.3679 L2313.3035,456.3679 L2323.3035,456.3679 L2313.3035,446.3679" fill="#FFFFFF" style="stroke:#000000;stroke-width:1;"/><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="80.1963" x="2218.7" y="463.5617">Minimal seed:</text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="85.2554" x="2218.7" y="478.5104">- test.user only</text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="89.6035" x="2218.7" y="493.4592">- Essential data</text></g><!--entity SpecsComp--><g class="entity" data-qualified-name="Test Environment.n.docker-compose.test.yaml..Specs.SpecsComp" data-source-line="101" id="ent0043"><rect fill="#FFFFFF" height="46.0986" rx="2.5" ry="2.5" style="stroke:#000000;stroke-width:1;" width="139.9893" x="3214.01" y="450.7379"/><rect fill="#FFFFFF" height="10" style="stroke:#000000;stroke-width:1;" width="15" x="3333.9993" y="455.7379"/><rect fill="#FFFFFF" height="2" style="stroke:#000000;stroke-width:1;" width="4" x="3331.9993" y="457.7379"/><rect fill="#FFFFFF" height="2" style="stroke:#000000;stroke-width:1;" width="4" x="3331.9993" y="461.7379"/><text fill="#000000" font-family="Arial" font-size="14" lengthAdjust="spacing" textLength="99.9893" x="3229.01" y="483.8697">Reqnroll + xUnit</text></g><g class="entity" data-qualified-name="Test Environment.n.docker-compose.test.yaml..Specs.GMN44" data-source-line="103" id="ent0045"><path d="M3389.21,408.9879 L3389.21,469.6079 L3354.37,473.6079 L3389.21,477.6079 L3389.21,538.5777 A0,0 0 0 0 3389.21,538.5777 L3538.7881,538.5777 A0,0 0 0 0 3538.7881,538.5777 L3538.7881,418.9879 L3528.7881,408.9879 L3389.21,408.9879 A0,0 0 0 0 3389.21,408.9879" fill="#FFFFFF" style="stroke:#000000;stroke-width:1;"/><path d="M3528.7881,408.9879 L3528.7881,418.9879 L3538.7881,418.9879 L3528.7881,408.9879" fill="#FFFFFF" style="stroke:#000000;stroke-width:1;"/><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="35.3945" x="3395.21" y="426.1817">Tests:</text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="104.0381" x="3395.21" y="441.1304">- Registration flow</text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="66.479" x="3395.21" y="456.0792">- Login flow</text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="96.8271" x="3395.21" y="471.0279">- Validation rules</text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="82.3989" x="3395.21" y="485.9766">- 404 handling</text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="3.6118" x="3395.21" y="500.9254"> </text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="124.2554" x="3395.21" y="515.8741">Uses: TestApiFactory</text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="128.5781" x="3395.21" y="530.8228">Mocks: Email services</text></g><!--entity UnitComp--><g class="entity" data-qualified-name="Test Environment.n.docker-compose.test.yaml..UnitTests.UnitComp" data-source-line="115" id="ent0048"><rect fill="#FFFFFF" height="46.0986" rx="2.5" ry="2.5" style="stroke:#000000;stroke-width:1;" width="115.0859" x="2733.46" y="450.7379"/><rect fill="#FFFFFF" height="10" style="stroke:#000000;stroke-width:1;" width="15" x="2828.5459" y="455.7379"/><rect fill="#FFFFFF" height="2" style="stroke:#000000;stroke-width:1;" width="4" x="2826.5459" y="457.7379"/><rect fill="#FFFFFF" height="2" style="stroke:#000000;stroke-width:1;" width="4" x="2826.5459" y="461.7379"/><text fill="#000000" font-family="Arial" font-size="14" lengthAdjust="spacing" textLength="75.0859" x="2748.46" y="483.8697">xUnit + Moq</text></g><g class="entity" data-qualified-name="Test Environment.n.docker-compose.test.yaml..UnitTests.GMN49" data-source-line="117" id="ent0050"><path d="M2883.71,379.0979 L2883.71,469.6079 L2848.91,473.6079 L2883.71,477.6079 L2883.71,568.4826 A0,0 0 0 0 2883.71,568.4826 L3106.2862,568.4826 A0,0 0 0 0 3106.2862,568.4826 L3106.2862,389.0979 L3096.2862,379.0979 L2883.71,379.0979 A0,0 0 0 0 2883.71,379.0979" fill="#FFFFFF" style="stroke:#000000;stroke-width:1;"/><path d="M3096.2862,379.0979 L3096.2862,389.0979 L3106.2862,389.0979 L3096.2862,379.0979" fill="#FFFFFF" style="stroke:#000000;stroke-width:1;"/><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="168.3398" x="2889.71" y="396.2917">Builds Dockerfile.tests, which</text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="188.5889" x="2889.71" y="411.2404">restores/builds against Core.slnx</text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="181.3652" x="2889.71" y="426.1892">then runs `dotnet test` for every</text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="181.3525" x="2889.71" y="441.1379">Features/*.Tests project in turn:</text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="124.9917" x="2889.71" y="456.0866">- Features.Auth.Tests</text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="156.0444" x="2889.71" y="471.0354">- Features.Breweries.Tests</text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="201.5762" x="2889.71" y="485.9841">- Features.UserManagement.Tests</text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="137.2554" x="2889.71" y="500.9328">- Features.Emails.Tests</text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="3.6118" x="2889.71" y="515.8815"> </text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="199.0181" x="2889.71" y="530.8303">Uses: Moq to mock each handler's</text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="186.437" x="2889.71" y="545.779">repository/service dependencies</text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="146.0024" x="2889.71" y="560.7277">No real database needed</text></g><!--entity Result1--><g class="entity" data-qualified-name="Results.Result1" data-source-line="135" id="ent0053"><path d="M3986.77,722.7279 L3986.77,769.9251 A2.5,2.5 0 0 0 3989.27,772.4251 L4072.7251,772.4251 A2.5,2.5 0 0 0 4075.2251,769.9251 L4075.2251,730.2279 L4065.2251,720.2279 L3989.27,720.2279 A2.5,2.5 0 0 0 3986.77,722.7279" fill="#FFFFFF" style="stroke:#000000;stroke-width:1;"/><path d="M4065.2251,720.2279 L4065.2251,727.7279 A2.5,2.5 0 0 0 4067.7251,730.2279 L4075.2251,730.2279" fill="#FFFFFF" style="stroke:#000000;stroke-width:1;"/><text fill="#000000" font-family="Arial" font-size="14" lengthAdjust="spacing" textLength="63.8066" x="3996.77" y="743.3597">api-specs/</text><text fill="#000000" font-family="Arial" font-size="14" lengthAdjust="spacing" textLength="60.6758" x="4004.5493" y="759.4583">results.trx</text></g><!--entity Result2--><g class="entity" data-qualified-name="Results.Result2" data-source-line="136" id="ent0054"><path d="M4110.25,730.7779 L4110.25,761.8765 A2.5,2.5 0 0 0 4112.75,764.3765 L4273.2461,764.3765 A2.5,2.5 0 0 0 4275.7461,761.8765 L4275.7461,738.2779 L4265.7461,728.2779 L4112.75,728.2779 A2.5,2.5 0 0 0 4110.25,730.7779" fill="#FFFFFF" style="stroke:#000000;stroke-width:1;"/><path d="M4265.7461,728.2779 L4265.7461,735.7779 A2.5,2.5 0 0 0 4268.2461,738.2779 L4275.7461,738.2779" fill="#FFFFFF" style="stroke:#000000;stroke-width:1;"/><text fill="#000000" font-family="Arial" font-size="14" lengthAdjust="spacing" textLength="145.4961" x="4120.25" y="751.4097">Features.Auth.Tests.trx</text></g><!--entity Result3--><g class="entity" data-qualified-name="Results.Result3" data-source-line="137" id="ent0055"><path d="M3931.53,987.8379 L3931.53,1018.9365 A2.5,2.5 0 0 0 3934.03,1021.4365 L4127.9675,1021.4365 A2.5,2.5 0 0 0 4130.4675,1018.9365 L4130.4675,995.3379 L4120.4675,985.3379 L3934.03,985.3379 A2.5,2.5 0 0 0 3931.53,987.8379" fill="#FFFFFF" style="stroke:#000000;stroke-width:1;"/><path d="M4120.4675,985.3379 L4120.4675,992.8379 A2.5,2.5 0 0 0 4122.9675,995.3379 L4130.4675,995.3379" fill="#FFFFFF" style="stroke:#000000;stroke-width:1;"/><text fill="#000000" font-family="Arial" font-size="14" lengthAdjust="spacing" textLength="178.9375" x="3941.53" y="1008.4697">Features.Breweries.Tests.trx</text></g><!--entity Result4--><g class="entity" data-qualified-name="Results.Result4" data-source-line="138" id="ent0056"><path d="M4165.01,987.8379 L4165.01,1018.9365 A2.5,2.5 0 0 0 4167.51,1021.4365 L4410.4817,1021.4365 A2.5,2.5 0 0 0 4412.9817,1018.9365 L4412.9817,995.3379 L4402.9817,985.3379 L4167.51,985.3379 A2.5,2.5 0 0 0 4165.01,987.8379" fill="#FFFFFF" style="stroke:#000000;stroke-width:1;"/><path d="M4402.9817,985.3379 L4402.9817,992.8379 A2.5,2.5 0 0 0 4405.4817,995.3379 L4412.9817,995.3379" fill="#FFFFFF" style="stroke:#000000;stroke-width:1;"/><text fill="#000000" font-family="Arial" font-size="14" lengthAdjust="spacing" textLength="227.9717" x="4175.01" y="1008.4697">Features.UserManagement.Tests.trx</text></g><!--entity Result5--><g class="entity" data-qualified-name="Results.Result5" data-source-line="139" id="ent0057"><path d="M4373.65,730.7779 L4373.65,761.8765 A2.5,2.5 0 0 0 4376.15,764.3765 L4549.8531,764.3765 A2.5,2.5 0 0 0 4552.3531,761.8765 L4552.3531,738.2779 L4542.3531,728.2779 L4376.15,728.2779 A2.5,2.5 0 0 0 4373.65,730.7779" fill="#FFFFFF" style="stroke:#000000;stroke-width:1;"/><path d="M4542.3531,728.2779 L4542.3531,735.7779 A2.5,2.5 0 0 0 4544.8531,738.2779 L4552.3531,738.2779" fill="#FFFFFF" style="stroke:#000000;stroke-width:1;"/><text fill="#000000" font-family="Arial" font-size="14" lengthAdjust="spacing" textLength="158.7031" x="4383.65" y="751.4097">Features.Emails.Tests.trx</text></g><g class="entity" data-qualified-name="Results.GMN58" data-source-line="142" id="ent0059"><path d="M4448.18,961.0179 L4448.18,1045.7615 A0,0 0 0 0 4448.18,1045.7615 L4563.8236,1045.7615 A0,0 0 0 0 4563.8236,1045.7615 L4563.8236,971.0179 L4553.8236,961.0179 L4504.26,961.0179 L4500.26,764.8179 L4496.26,961.0179 L4448.18,961.0179 A0,0 0 0 0 4448.18,961.0179" fill="#FFFFFF" style="stroke:#000000;stroke-width:1;"/><path d="M4553.8236,961.0179 L4553.8236,971.0179 L4563.8236,971.0179 L4553.8236,961.0179" fill="#FFFFFF" style="stroke:#000000;stroke-width:1;"/><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="66.4536" x="4454.18" y="978.2117">TRX format</text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="76.6099" x="4454.18" y="993.1604">Readable by:</text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="83.8208" x="4454.18" y="1008.1092">- Visual Studio</text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="92.4727" x="4454.18" y="1023.0579">- Azure DevOps</text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="94.6436" x="4454.18" y="1038.0066">- GitHub Actions</text></g><!--entity Developer--><g class="entity" data-qualified-name="Developer" data-source-line="9" id="ent0002"><ellipse cx="1850.9967" cy="181.7979" fill="#FFFFFF" rx="8" ry="8" style="stroke:#000000;stroke-width:1;"/><path d="M1850.9967,189.7979 L1850.9967,216.7979 M1837.9967,197.7979 L1863.9967,197.7979 M1850.9967,216.7979 L1837.9967,231.7979 M1850.9967,216.7979 L1863.9967,231.7979" fill="none" style="stroke:#000000;stroke-width:1;"/><text fill="#000000" font-family="Arial" font-size="14" lengthAdjust="spacing" textLength="63.8135" x="1819.09" y="246.9297">Developer</text></g><!--entity Host--><g class="entity" data-qualified-name="Host" data-source-line="10" id="ent0003"><path d="M1807.2238,460.8905 C1809.5433,455.6754 1814.1764,453.9668 1818.5056,458.5848 C1822.5161,453.7299 1825.8662,453.7385 1829.1817,459.2972 C1831.8475,453.0646 1835.1877,451.7664 1840.3597,456.8137 C1843.3638,451.5959 1847.5803,451.5548 1851.152,456.1921 C1855.5891,450.4446 1861.4403,451.2411 1864.4661,457.728 C1867.3088,453.3083 1871.4114,453.3512 1874.3866,457.576 C1878.0741,451.6683 1883.3778,453.1859 1885.9902,458.671 C1890.0299,454.6827 1894.0976,453.9629 1896.8091,460.0914 C1904.2757,462.8959 1904.8124,468.2202 1900.1394,473.9432 C1907.7148,480.4041 1905.5716,486.2337 1897.3446,489.9324 C1894.1717,494.7729 1890.5099,494.7702 1886.9191,490.4057 C1883.79,496.0424 1880.0121,497.0853 1875.2219,492.2636 C1872.6485,499.0324 1868.1843,498.1693 1863.8399,494.1283 C1861.1975,499.5047 1857.1262,500.6107 1852.8279,495.9439 C1849.4522,502.0283 1844.1266,500.9243 1841.1526,495.5352 C1835.9937,500.3217 1831.1549,499.5637 1829.0035,492.4618 C1825.5359,497.4122 1822.2163,496.6042 1818.8274,492.3745 C1813.94,496.2784 1809.2593,495.8113 1807.4093,489.1056 C1798.6961,487.7003 1797.2013,481.0802 1801.8067,474.5488 C1797.9166,468.4061 1798.4491,462.0101 1807.2238,460.8905" fill="#FFFFFF" style="stroke:#000000;stroke-width:1;"/><text fill="#000000" font-family="Arial" font-size="14" lengthAdjust="spacing" textLength="77.0205" x="1812.49" y="478.8697">Docker Host</text></g><g class="entity" data-qualified-name="GMN86" data-source-line="179" id="ent0087"><path d="M1797.01,1120.7079 L1797.01,1190.5028 L2046.9954,1190.5028 L2046.9954,1130.7079 L2036.9954,1120.7079 L1797.01,1120.7079" fill="#FFFFFF" style="stroke:#000000;stroke-width:1;"/><path d="M2036.9954,1120.7079 L2036.9954,1130.7079 L2046.9954,1130.7079 L2036.9954,1120.7079" fill="#FFFFFF" style="stroke:#000000;stroke-width:1;"/><text fill="#000000" font-family="Arial" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="228.9854" x="1803.01" y="1137.9017">Dev Network (bridge: biergarten-dev)</text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="78.0317" x="1803.01" y="1152.8504">Internal DNS:</text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="226.8525" x="1803.01" y="1167.7992">- sql-server (resolves to SQL container)</text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="182.0762" x="1803.01" y="1182.7479">- api (resolves to API container)</text></g><g class="entity" data-qualified-name="GMN89" data-source-line="186" id="ent0090"><path d="M3630.21,983.4379 L3630.21,1023.3353 L3883.7945,1023.3353 L3883.7945,993.4379 L3873.7945,983.4379 L3630.21,983.4379" fill="#FFFFFF" style="stroke:#000000;stroke-width:1;"/><path d="M3873.7945,983.4379 L3873.7945,993.4379 L3883.7945,993.4379 L3873.7945,983.4379" fill="#FFFFFF" style="stroke:#000000;stroke-width:1;"/><text fill="#000000" font-family="Arial" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="232.5845" x="3636.21" y="1000.6317">Test Network (bridge: biergarten-test)</text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="161.8652" x="3636.21" y="1015.5804">All test components isolated</text></g><g class="entity" data-qualified-name="GMN92" data-source-line="192" id="ent0093"><path d="M1939.69,431.4179 L1939.69,516.1615 L2128.3189,516.1615 L2128.3189,441.4179 L2118.3189,431.4179 L1939.69,431.4179" fill="#FFFFFF" style="stroke:#000000;stroke-width:1;"/><path d="M2118.3189,431.4179 L2118.3189,441.4179 L2128.3189,441.4179 L2118.3189,431.4179" fill="#FFFFFF" style="stroke:#000000;stroke-width:1;"/><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="82.3672" x="1945.69" y="448.6117">Startup Order:</text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="167.6289" x="1945.69" y="463.5604">1. SQL Server (health check)</text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="137.998" x="1945.69" y="478.5092">2. Migrations (run-once)</text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="108.3926" x="1945.69" y="493.4579">3. Seed (run-once)</text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="119.9517" x="1945.69" y="508.4066">4. API (long-running)</text></g><g class="entity" data-qualified-name="GMN95" data-source-line="200" id="ent0096"><path d="M3629.92,183.9279 L3629.92,238.774 L3778.0889,238.774 L3778.0889,193.9279 L3768.0889,183.9279 L3629.92,183.9279" fill="#FFFFFF" style="stroke:#000000;stroke-width:1;"/><path d="M3768.0889,183.9279 L3768.0889,193.9279 L3778.0889,193.9279 L3768.0889,183.9279" fill="#FFFFFF" style="stroke:#000000;stroke-width:1;"/><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="89.5972" x="3635.92" y="201.1217">Test Execution:</text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="127.1689" x="3635.92" y="216.0704">All tests run in parallel</text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="112.7407" x="3635.92" y="231.0192">Results aggregated</text></g><g class="entity" data-qualified-name="ProductionNote" data-source-line="207" id="ent0098"><path d="M3813.4,131.6079 L3813.4,291.0952 L4062.6046,291.0952 L4062.6046,141.6079 L4052.6046,131.6079 L3813.4,131.6079" fill="#FFFFFF" style="stroke:#000000;stroke-width:1;"/><path d="M4052.6046,131.6079 L4052.6046,141.6079 L4062.6046,141.6079 L4052.6046,131.6079" fill="#FFFFFF" style="stroke:#000000;stroke-width:1;"/><text fill="#000000" font-family="Arial" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="228.2046" x="3819.4" y="148.8017">Production Deployment (not shown):</text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="3.6118" x="3819.4" y="163.7504"> </text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="85.2681" x="3819.4" y="178.6992">Would include:</text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="202.5156" x="3819.4" y="193.6479">• Azure SQL Database / AWS RDS</text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="172.9102" x="3819.4" y="208.5966">• Azure Container Apps / ECS</text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="165.6738" x="3819.4" y="223.5454">• Azure Key Vault for secrets</text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="201.8174" x="3819.4" y="238.4941">• Application Insights / CloudWatch</text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="90.562" x="3819.4" y="253.4428">• Load balancer</text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="118.6948" x="3819.4" y="268.3915">• HTTPS termination</text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="130.2476" x="3819.4" y="283.3403">• CDN for static assets</text></g><!--link Developer to Host--><g class="link" data-entity-1="ent0002" data-entity-2="ent0003" data-link-type="dependency" data-source-line="151" id="lnk61"><path d="M1851,250.3579 C1851,305.7579 1851,399.5079 1851,444.5679" fill="none" id="Developer-to-Host" style="stroke:#000000;stroke-width:1;"/><polygon fill="#000000" points="1851,450.5679,1855,441.5679,1851,445.5679,1847,441.5679,1851,450.5679" style="stroke:#000000;stroke-width:1;"/><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="113.4517" x="1737" y="347.6517">docker compose up</text></g><!--link Host to DevAPI--><g class="link" data-entity-1="ent0003" data-entity-2="ent0011" data-link-type="dependency" data-source-line="152" id="lnk62"><path d="M1851,497.2879 C1851,500.9779 1851,503.6079 1851,503.6079 C1851,503.6079 1430.5825,503.6079 1010.165,503.6079 C957.6128,503.6079 905.0606,503.6079 853.3296,503.6079 C840.3968,503.6079 827.5154,503.6079 814.6981,503.6079 C808.2894,503.6079 801.8968,503.6079 795.5218,503.6079 C792.3344,503.6079 795.1513,503.6079 791.9728,503.6079" fill="none" id="Host-to-DevAPI" style="stroke:#000000;stroke-width:1;"/><polygon fill="#000000" points="785.9728,503.6079,794.9728,507.6079,790.9728,503.6079,794.9728,499.6079,785.9728,503.6079" style="stroke:#000000;stroke-width:1;"/><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="116.3589" x="785.11" y="500.8017">http://localhost:8080</text></g><!--link DevMig to DevDB--><g class="link" data-entity-1="ent0018" data-entity-2="ent0005" data-link-type="dependency" data-source-line="155" id="lnk63"><path d="M1045,1062.5253 C1045,1063.2854 1045,1064.0325 1045,1064.7662 C1045,1066.2337 1045,1067.6479 1045,1069.0065 C1045,1071.7236 1045,1074.2179 1045,1076.4699 C1045,1085.4777 1045,1090.6079 1045,1090.6079 C1045,1090.6079 1051.4688,1090.6079 1062.7891,1090.6079 C1068.4492,1090.6079 1075.3223,1090.6079 1083.2061,1090.6079 C1085.177,1090.6079 1087.2111,1090.6079 1089.3053,1090.6079 C1090.3523,1090.6079 1085.4144,1090.6079 1086.4911,1090.6079" fill="none" id="DevMig-to-DevDB" style="stroke:#000000;stroke-width:1;"/><polygon fill="#000000" points="1092.4911,1090.6079,1083.4911,1086.6079,1087.4911,1090.6079,1083.4911,1094.6079,1092.4911,1090.6079" style="stroke:#000000;stroke-width:1;"/><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="101.8799" x="1021.47" y="1087.8017">1. Run migrations</text></g><!--reverse link DevDB to DevMig--><g class="link" data-entity-1="ent0005" data-entity-2="ent0018" data-link-type="dependency" data-source-line="158" id="lnk67"><path d="M1439.05,874.6528 C1439.05,872.6391 1439.05,876.6235 1439.05,874.6079 C1439.05,810.1079 1439.05,745.6079 1439.05,745.6079 C1439.05,745.6079 1343.5925,745.6079 1246.6438,745.6079 C1198.1694,745.6079 1149.3222,745.6079 1111.848,745.6079 C1093.1109,745.6079 1077.217,745.6079 1065.6346,745.6079 C1062.739,745.6079 1060.1129,745.6079 1057.7791,745.6079 C1056.6123,745.6079 1055.5185,745.6079 1054.5007,745.6079 C1053.9918,745.6079 1053.5019,745.6079 1053.0314,745.6079" fill="none" id="DevDB-backto-DevMig" style="stroke:#000000;stroke-width:1;stroke-dasharray:7,7;"/><polygon fill="#000000" points="1439.05,880.6528,1443.05,871.6528,1439.05,875.6528,1435.05,871.6528,1439.05,880.6528" style="stroke:#000000;stroke-width:1;"/><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="71.5698" x="1308.9" y="742.8017">depends_on</text></g><!--link DevSeed to DevDB--><g class="link" data-entity-1="ent0023" data-entity-2="ent0005" data-link-type="dependency" data-source-line="156" id="lnk64"><path d="M1510.9201,746.6079 C1510.7648,746.6079 1510.6079,746.6079 1510.4492,746.6079 C1509.1799,746.6079 1507.8034,746.6079 1506.3438,746.6079 C1500.505,746.6079 1493.335,746.6079 1486.37,746.6079 C1472.44,746.6079 1459.33,746.6079 1459.33,746.6079 C1459.33,746.6079 1459.33,806.8529 1459.33,868.9816 C1459.33,872.8646 1459.33,870.7551 1459.33,874.6386" fill="none" id="DevSeed-to-DevDB" style="stroke:#000000;stroke-width:1;"/><polygon fill="#000000" points="1459.33,880.6386,1463.33,871.6386,1459.33,875.6386,1455.33,871.6386,1459.33,880.6386" style="stroke:#000000;stroke-width:1;"/><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="73.728" x="1385.33" y="842.3217">2. Seed data</text></g><!--link DevAPI to DevDB--><g class="link" data-entity-1="ent0011" data-entity-2="ent0005" data-link-type="dependency" data-source-line="157" id="lnk65"><path d="M143,766.5779 C143,805.2079 143,885.6079 143,885.6079 C143,885.6079 471.9175,885.6079 800.835,885.6079 C883.0644,885.6079 965.2938,885.6079 1042.3838,885.6079 C1052.02,885.6079 1061.576,885.6079 1071.0416,885.6079 C1075.7744,885.6079 1080.4846,885.6079 1085.171,885.6079 C1087.5142,885.6079 1083.8514,885.6079 1086.1826,885.6079" fill="none" id="DevAPI-to-DevDB" style="stroke:#000000;stroke-width:1;"/><polygon fill="#000000" points="1092.1826,885.6079,1083.1826,881.6079,1087.1826,885.6079,1083.1826,889.6079,1092.1826,885.6079" style="stroke:#000000;stroke-width:1;"/><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="110.5571" x="688.83" y="882.8017">3. Connect & serve</text></g><!--reverse link DevMig to DevSeed--><g class="link" data-entity-1="ent0018" data-entity-2="ent0023" data-link-type="dependency" data-source-line="159" id="lnk69"><path d="M1059.2214,734.6079 C1061.7366,734.6079 1062.115,734.6079 1065.353,734.6079 C1078.3049,734.6079 1096.8077,734.6079 1119.0109,734.6079 C1163.4175,734.6079 1222.6263,734.6079 1281.835,734.6079 C1341.0438,734.6079 1400.2525,734.6079 1444.6591,734.6079 C1466.8623,734.6079 1485.3651,734.6079 1498.317,734.6079 C1501.555,734.6079 1504.446,734.6079 1506.9612,734.6079 C1508.2188,734.6079 1509.3825,734.6079 1510.4486,734.6079 C1510.5818,734.6079 1510.7136,734.6079 1510.8438,734.6079" fill="none" id="DevMig-backto-DevSeed" style="stroke:#000000;stroke-width:1;stroke-dasharray:7,7;"/><polygon fill="#000000" points="1053.2214,734.6079,1062.2214,738.6079,1058.2214,734.6079,1062.2214,730.6079,1053.2214,734.6079" style="stroke:#000000;stroke-width:1;"/><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="71.5698" x="1209.83" y="731.8017">depends_on</text></g><!--reverse link DevSeed to DevAPI--><g class="link" data-entity-1="ent0023" data-entity-2="ent0011" data-link-type="dependency" data-source-line="160" id="lnk71"><path d="M1519.33,653.2254 C1519.33,652.6935 1519.33,657.364 1519.33,656.8345 C1519.33,652.599 1519.33,648.4465 1519.33,644.4398 C1519.33,636.4264 1519.33,628.9961 1519.33,622.6507 C1519.33,609.9597 1519.33,601.6079 1519.33,601.6079 C1519.33,601.6079 1189.04,601.6079 858.75,601.6079 C838.1069,601.6079 817.4638,601.6079 796.9013,601.6079 C791.7606,601.6079 786.6251,601.6079 781.4958,601.6079" fill="none" id="DevSeed-backto-DevAPI" style="stroke:#000000;stroke-width:1;stroke-dasharray:7,7;"/><polygon fill="#000000" points="1519.33,659.2254,1523.33,650.2254,1519.33,654.2254,1515.33,650.2254,1519.33,659.2254" style="stroke:#000000;stroke-width:1;"/><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="71.5698" x="796.64" y="598.8017">depends_on</text></g><!--link TestMig to TestDB--><g class="link" data-entity-1="ent0035" data-entity-2="ent0029" data-link-type="dependency" data-source-line="163" id="lnk72"><path d="M2656.0705,473.6079 C2656.1328,473.6079 2656.1953,473.6079 2656.258,473.6079 C2656.7599,473.6079 2657.2776,473.6079 2657.8091,473.6079 C2662.0606,473.6079 2667.1913,473.6079 2672.1425,473.6079 C2682.045,473.6079 2691.23,473.6079 2691.23,473.6079 C2691.23,473.6079 2691.23,633.6079 2691.23,633.6079 C2691.23,633.6079 2717.9019,633.6079 2757.9097,633.6079 C2759.1599,633.6079 2754.4232,633.6079 2755.6991,633.6079" fill="none" id="TestMig-to-TestDB" style="stroke:#000000;stroke-width:1;"/><polygon fill="#000000" points="2761.6991,633.6079,2752.6991,629.6079,2756.6991,633.6079,2752.6991,637.6079,2761.6991,633.6079" style="stroke:#000000;stroke-width:1;"/><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="57.8018" x="2813.58" y="630.8017">1. Migrate</text></g><!--reverse link TestDB to TestMig--><g class="link" data-entity-1="ent0029" data-entity-2="ent0035" data-link-type="dependency" data-source-line="168" id="lnk77"><path d="M2754.0214,811.6079 C2752.3872,811.6079 2754.3048,811.6079 2752.6947,811.6079 C2749.4744,811.6079 2746.3031,811.6079 2743.1845,811.6079 C2736.9474,811.6079 2730.9211,811.6079 2725.1359,811.6079 C2678.8544,811.6079 2648,811.6079 2648,811.6079 C2648,811.6079 2648,731.0654 2648,648.6354 C2648,607.4204 2648,565.7335 2648,533.4066 C2648,529.3657 2648,525.4711 2648,521.742" fill="none" id="TestDB-backto-TestMig" style="stroke:#000000;stroke-width:1;stroke-dasharray:7,7;"/><polygon fill="#000000" points="2760.0214,811.6079,2751.0214,807.6079,2755.0214,811.6079,2751.0214,815.6079,2760.0214,811.6079" style="stroke:#000000;stroke-width:1;"/><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="71.5698" x="2686.47" y="808.8017">depends_on</text></g><!--link TestSeed to TestDB--><g class="link" data-entity-1="ent0037" data-entity-2="ent0029" data-link-type="dependency" data-source-line="164" id="lnk73"><path d="M2380.507,199.6079 C2386.055,199.6079 2394.1921,199.6079 2404.5484,199.6079 C2425.261,199.6079 2454.8505,199.6079 2490.3578,199.6079 C2561.3725,199.6079 2656.0588,199.6079 2750.745,199.6079 C2940.1175,199.6079 3129.49,199.6079 3129.49,199.6079 C3129.49,199.6079 3129.49,336.1079 3129.49,472.6079 C3129.49,506.7329 3129.49,540.8579 3129.49,572.85 C3129.49,588.8461 3129.49,604.309 3129.49,618.9721 C3129.49,622.6379 3129.49,626.2537 3129.49,629.8153 C3129.49,630.7057 3129.49,625.5927 3129.49,626.4763" fill="none" id="TestSeed-to-TestDB" style="stroke:#000000;stroke-width:1;"/><polygon fill="#000000" points="3129.49,632.4763,3133.49,623.4763,3129.49,627.4763,3125.49,623.4763,3129.49,632.4763" style="stroke:#000000;stroke-width:1;"/><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="44.8145" x="2979.44" y="196.8017">2. Seed</text></g><!--link Specs to TestDB--><g class="link" data-entity-1="ent0042" data-entity-2="ent0029" data-link-type="dependency" data-source-line="165" id="lnk74"><path d="M3574,563.2582 C3574,563.7462 3574,564.2351 3574,564.725 C3574,565.7046 3574,566.6878 3574,567.6743 C3574,583.4579 3574,600.0854 3574,616.5879 C3574,682.5979 3574,746.6079 3574,746.6079 C3574,746.6079 3471.0025,746.6079 3365.5913,746.6079 C3312.8856,746.6079 3259.5766,746.6079 3218.237,746.6079 C3197.5673,746.6079 3179.8899,746.6079 3166.7765,746.6079 C3160.2198,746.6079 3160.8041,746.6079 3156.7259,746.6079" fill="none" id="Specs-to-TestDB" style="stroke:#000000;stroke-width:1;"/><polygon fill="#000000" points="3150.7259,746.6079,3159.7259,750.6079,3155.7259,746.6079,3159.7259,742.6079,3150.7259,746.6079" style="stroke:#000000;stroke-width:1;"/><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="100.4517" x="3393.37" y="743.8017">3. Integration test</text></g><!--link UnitTests to TestDB--><g class="link" data-entity-1="ent0047" data-entity-2="ent0029" data-link-type="dependency" data-source-line="166" id="lnk75"><path d="M3142,593.8071 C3142,594.3035 3142,594.8001 3142,595.2971 C3142,596.291 3142,597.2859 3142,598.2817 C3142,602.2648 3142,606.2614 3142,610.2579 C3142,614.2543 3142,618.2504 3142,622.2326 C3142,624.2237 3142,626.2113 3142,628.1937 C3142,629.1849 3142,630.1748 3142,631.1631 C3142,631.4102 3142,625.6572 3142,625.9041" fill="none" id="UnitTests-to-TestDB" style="stroke:#000000;stroke-width:1;stroke-dasharray:7,7;"/><polygon fill="#000000" points="3142,631.9041,3146,622.9041,3142,626.9041,3138,622.9041,3142,631.9041" style="stroke:#000000;stroke-width:1;"/><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="133.707" x="2997.731" y="577.2717">depends_on for startup</text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="153.1689" x="2988" y="592.2204">ordering only (Moq mocks,</text><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="110.5698" x="3009.2996" y="607.1692">no real connection)</text></g><!--reverse link TestMig to TestSeed--><g class="link" data-entity-1="ent0035" data-entity-2="ent0037" data-link-type="dependency" data-source-line="169" id="lnk79"><path d="M2648,380.3952 C2648,365.2273 2648,352.4141 2648,336.5554 C2648,273.1204 2648,211.6079 2648,211.6079 C2648,211.6079 2583.245,211.6079 2516.4663,211.6079 C2483.0769,211.6079 2449.1816,211.6079 2422.6217,211.6079 C2409.3418,211.6079 2397.8957,211.6079 2389.2637,211.6079 C2387.1057,211.6079 2385.1236,211.6079 2383.3327,211.6079 C2382.4372,211.6079 2381.5895,211.6079 2380.7916,211.6079 C2380.5921,211.6079 2380.3957,211.6079 2380.2025,211.6079" fill="none" id="TestMig-backto-TestSeed" style="stroke:#000000;stroke-width:1;stroke-dasharray:7,7;"/><polygon fill="#000000" points="2648,386.3952,2652,377.3952,2648,381.3952,2644,377.3952,2648,386.3952" style="stroke:#000000;stroke-width:1;"/><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="71.5698" x="2569.11" y="208.8017">depends_on</text></g><!--reverse link TestSeed to Specs--><g class="link" data-entity-1="ent0037" data-entity-2="ent0042" data-link-type="dependency" data-source-line="170" id="lnk81"><path d="M2386.9998,242.6079 C2393.3839,242.6079 2397.071,242.6079 2405.2896,242.6079 C2438.1639,242.6079 2485.1272,242.6079 2541.4831,242.6079 C2654.195,242.6079 2804.4775,242.6079 2954.76,242.6079 C3255.325,242.6079 3555.89,242.6079 3555.89,242.6079 C3555.89,242.6079 3555.89,257.0454 3555.89,278.7016 C3555.89,289.5297 3555.89,302.1625 3555.89,315.6977 C3555.89,322.4653 3555.89,329.4584 3555.89,336.5644 C3555.89,338.3409 3555.89,340.1244 3555.89,341.9132 C3555.89,342.8077 3555.89,343.7034 3555.89,344.6002" fill="none" id="TestSeed-backto-Specs" style="stroke:#000000;stroke-width:1;stroke-dasharray:7,7;"/><polygon fill="#000000" points="2380.9998,242.6079,2389.9998,246.6079,2385.9998,242.6079,2389.9998,238.6079,2380.9998,242.6079" style="stroke:#000000;stroke-width:1;"/><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="71.5698" x="2982.63" y="239.8017">depends_on</text></g><!--reverse link TestSeed to UnitTests--><g class="link" data-entity-1="ent0037" data-entity-2="ent0047" data-link-type="dependency" data-source-line="171" id="lnk83"><path d="M2386.6475,246.6079 C2392.2871,246.6079 2394.5586,246.6079 2405.0859,246.6079 C2426.1406,246.6079 2456.2188,246.6079 2492.3125,246.6079 C2564.5,246.6079 2660.75,246.6079 2757,246.6079 C2949.5,246.6079 3142,246.6079 3142,246.6079 C3142,246.6079 3142,259.9329 3142,280.1286 C3142,290.2265 3142,302.0421 3142,314.7686" fill="none" id="TestSeed-backto-UnitTests" style="stroke:#000000;stroke-width:1;stroke-dasharray:7,7;"/><polygon fill="#000000" points="2380.6475,246.6079,2389.6475,250.6079,2385.6475,246.6079,2389.6475,242.6079,2380.6475,246.6079" style="stroke:#000000;stroke-width:1;"/><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="71.5698" x="2780.83" y="243.8017">depends_on</text></g><!--link Specs to Results--><g class="link" data-entity-1="ent0042" data-entity-2="ent0052" data-link-type="dependency" data-source-line="174" id="lnk84"><path d="M3582.5708,473.6079 C3583.3686,473.6079 3584.2199,473.6079 3585.1238,473.6079 C3586.9315,473.6079 3588.9495,473.6079 3591.1703,473.6079 C3600.0538,473.6079 3612.1831,473.6079 3627.0861,473.6079 C3656.892,473.6079 3697.7924,473.6079 3746.0092,473.6079 C3842.4428,473.6079 3968.1419,473.6079 4092.8813,473.6079 C4342.36,473.6079 4588,473.6079 4588,473.6079 C4588,473.6079 4588,537.5929 4588,603.5779 C4588,620.0741 4588,636.6954 4588,652.4731 C4588,654.4453 4588,656.4043 4588,658.3483 C4588,658.8343 4588,691.5166 4588,692.0007" fill="none" id="Specs-to-Results" style="stroke:#000000;stroke-width:1;"/><polygon fill="#000000" points="4588,698.0007,4592,689.0007,4588,693.0007,4584,689.0007,4588,698.0007" style="stroke:#000000;stroke-width:1;"/><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="67.1836" x="4149.34" y="470.8017">Export TRX</text></g><!--link UnitTests to Results--><g class="link" data-entity-1="ent0047" data-entity-2="ent0052" data-link-type="dependency" data-source-line="175" id="lnk85"><path d="M3150.078,473.6079 C3150.1911,473.6079 3150.3051,473.6079 3150.4197,473.6079 C3150.6491,473.6079 3150.8814,473.6079 3151.1164,473.6079 C3151.5864,473.6079 3152.0674,473.6079 3152.5574,473.6079 C3153.5374,473.6079 3154.5536,473.6079 3155.5913,473.6079 C3157.6668,473.6079 3159.8284,473.6079 3161.9588,473.6079 C3170.48,473.6079 3178.5,473.6079 3178.5,473.6079 C3178.5,473.6079 3178.5,784.6079 3178.5,784.6079 C3178.5,784.6079 3530.875,784.6079 3883.25,784.6079 C3888.7559,784.6079 3888.2617,784.6079 3893.7662,784.6079" fill="none" id="UnitTests-to-Results" style="stroke:#000000;stroke-width:1;"/><polygon fill="#000000" points="3899.7662,784.6079,3890.7662,780.6079,3894.7662,784.6079,3890.7662,788.6079,3899.7662,784.6079" style="stroke:#000000;stroke-width:1;"/><text fill="#000000" font-family="Arial" font-size="13" lengthAdjust="spacing" textLength="174.8271" x="3553.51" y="781.8017">Export TRX (one .trx per slice)</text></g><!--link DevDB to GMN86--><g class="link" data-entity-1="ent0005" data-entity-2="ent0087" data-link-type="association" data-source-line="179" id="lnk88"><path d="M1471.0283,1003.6079 C1472.6977,1003.6079 1474.4181,1003.6079 1476.1025,1003.6079 C1482.84,1003.6079 1489,1003.6079 1489,1003.6079 C1489,1003.6079 1489,1125.6079 1489,1125.6079 C1489,1125.6079 1668.88,1125.6079 1796.76,1125.6079" fill="none" id="DevDB-GMN86" style="stroke:#000000;stroke-width:1;stroke-dasharray:7,7;"/></g><!--link TestDB to GMN89--><g class="link" data-entity-1="ent0029" data-entity-2="ent0090" data-link-type="association" data-source-line="186" id="lnk91"><path d="M3150.0844,1003.6079 C3151.7677,1003.6079 3153.7117,1003.6079 3155.903,1003.6079 C3164.6682,1003.6079 3177.3908,1003.6079 3193.2203,1003.6079 C3224.8794,1003.6079 3268.9663,1003.6079 3318.6775,1003.6079 C3418.1,1003.6079 3540.02,1003.6079 3630.01,1003.6079" fill="none" id="TestDB-GMN89" style="stroke:#000000;stroke-width:1;stroke-dasharray:7,7;"/></g><!--link GMN92 to DevMig--><g class="link" data-entity-1="ent0093" data-entity-2="ent0018" data-link-type="association" data-source-line="192" id="lnk94"><path d="M1939.33,509.6079 C1689.67,509.6079 1032.48,509.6079 1032.48,509.6079 C1032.48,509.6079 1032.48,568.8579 1032.48,628.1079 C1032.48,635.5141 1032.48,642.9204 1032.48,650.2109 C1032.48,652.0335 1032.48,653.8489 1032.48,655.6553 C1032.48,656.5584 1032.48,657.4594 1032.48,658.3578" fill="none" id="GMN92-DevMig" style="stroke:#000000;stroke-width:1;stroke-dasharray:7,7;"/></g><!--link GMN95 to Specs--><g class="link" data-entity-1="ent0096" data-entity-2="ent0042" data-link-type="association" data-source-line="200" id="lnk97"><path d="M3629.51,223.6079 C3600.46,223.6079 3574,223.6079 3574,223.6079 C3574,223.6079 3574,282.3054 3574,342.8366 C3574,343.3095 3574,343.7825 3574,344.2556" fill="none" id="GMN95-Specs" style="stroke:#000000;stroke-width:1;stroke-dasharray:7,7;"/></g><?plantuml-src bLZRRYEv4NtlhwXuWOpiNRKism4Mmdg0jYHdd5Yo8idZ3J20b-gc9SOKsKEoVKamGBubdvOlIHNxgekz4pyOBTOXMTTJrVq7j-9h3gbaGWNsKQYK6RQ61OiVbqPdAkbhgGtySEd_6eY4Fx1Ckakjt9ZX2P4HJ3RaKYZkNbCEshYL3W8ddEGmqF4ZDp3WgTIlQwuSxejNml7OPOO7mGSOlZXk59DWNwtZQnkms6dQySIbJha9Ogcp10wAapvfwmw0MVyG12dgpPOSnJdUNp5KJy9eHSzVL2ln6zknNgVQyZ3XJ-4hMyl30_XXU7fvSZc0VmK1WD897ZFxspNCk7dY1dUkOnEkHMoqrGykn0CwQsk_oexrWDx9ySb9MpB7hJlqAg4EWmiy3V0lOOujcCKZBmGtIsOSLr_Ke5YjuLTAeLNv7e0KdISK77JFJayF_Det_rzfny68vSeLm8Q9lMAf3L6_FvpCxuUtrz7vtwlLMNG_YMQpkvlfuFpewAXQ7ytGsFl9rU2yzdKX_AnbjkQsFdbHsT16_xN9E2_ZAl6w1QHevSHeSWLzp1DCCUz7_1tsjU6LbmYGc-oZeYXe1z5i4ew7So0aT8yz5e7TeEcOduz_FkxHFsXzciydrOaJbEyWkuJiviZP1lGa-7_SEfkWNlsRwV1-EFvyDRqPZuRZ-NaZuoheuE9-Dfn-7axFCK_QUPuqXUDeD3ol4w8fkiMDdJ9GbU0lTtCyiJyTpkjuZkQJ-oDeTOz_X2U6LRYGt1wMeVl4cNGhwAzu_5YQq5dbYnYjL8j2tVsX6ucbOKvePJ5k9bDjhU8wRYZTZLkPqs6zr-FnPxVsya8xfzU5GjDCsHuC5hSfhAjDxuMWVpsCflU3Q1vTHBFX-GEJbXT2f1OqnO9MFTXo-duJPvmd-uoZzNUi8x67qiDRXlKD9pwe5UyU7mCH16IebwsMhtNiZVOq0QtRMQSVTKQ_7bO0sXFI7c1nZBJizbYxvRfDQxyrk75E2hnBYlwwaXMHzq-7ns-oeh2QI2y1eQnZbGVfajzXFw_71WNcczxamBDtEV3ISBkgj03EuXLWLCjGRAQCCnd_7deZJzJy1j3YAJLCm-JXzvPDtH38lE-kcRrPkddMzwJe6vav4agigSiYfhSdpRIIhzNoq5ey6Vix_3xJXxEKnsJsbNAyCCOhQtEzlNXNwId_geoM4dw4bribN8tj8sX_mFsfjV9JlXJM5JS-IFtSAA-bs5hwpAH8SgZ9a30hmTdn6QoOId1-MPO9ScinE_nrKIek_K1IEcU4XOEouPe9SgPv4Z6txtWeGzjyUP6BBf4TSEonuL7eRVa9tSxHAqMhp1r6tl3INQTvJw77Hlfh1NtRNHUPa4WL-U3q86HUvdZfyqh4gmA4sg1rt7OMEPej6LMKxyAXbUgbmE7OI9vJ5dvBjCDHp-VER_20inesmie_fOcTmaH8ZVu7JdjOfu02LOUlSaQKkLKEtfLT6FxCZS2dDm0OAZDY2dcEcEqjb0zNUSP6aD6Lu3IiqKavW_XSuEQ3hHo432ae0pf5k74K9XBcAXPL7eqr0ejwySIdiCvuif-O7xHCiEGEFDUWUZXMsmxDcqJqME5Fdf_oR9ZcOfyB54CuOAbeMoeKtEBZH_BGcPS6lbkXztXv2tkoYzto-jQ6qzqD-wAmjUjiTrSpAbleF-KLjCbYy-clb6zhbcVubBE4XXzOlEPPXLKkR8PHcBai4RfOY_w9br63lqbjiVHduJvb2uZYidjM8VgsyKg2lPTR6rJpCRJR7_sB1_GWxw1GT538qi0B255Ck3rOEPVsEXs9tLwkKEedLxgX-RQoaKt5a5MSWlsq1zsGvgLcjo-7bIRg9FI3IKxOXG9D-Mb88xcYIloZvorUtXLcQLZZSctilLRLDHM0qDi8kgS2UFW60ctrNN_3oB8jadx5sE3Dp9iX3wfMjm4eB0poXh8XGkEQtOVgAgXfD0mRq5etJrquEnYNfL-KDbYIs09y8uGMqG9nWltfYr95RSUv__06dBPB6tBRznnVMr53TXoOsr83TXtOCECTLEdcWWs0lz0KrN1LIIFOkRo8QgbnzbiGQ563eje4IdyhaVuEwROnTy_QFFgYiK6ZK44_vBc4LVNBuYC-LjZMmeXaoNjRRvE7ltGM7n5D4VHLDnZFg9xRZN4UMcYPba_S4bdJE5etJGz5Kjp4K5usC5M1R-kQHovNrhlmFMtzD5Qe6-7iuYVxgZzRA4VZndKVa8nyYc7HVSqu3QeDdpcT5Wx3rC13I-mDPICv0QkY7hwXLRp8nVHsHuQVb4L3l03rEmsAJWj2s5Wy2xrZMbAhPHi52ZD-npc5KZvvWdpgmfJWSKQtz1gcMne8gB7J5o0fkGoWoYAsN1g-t776nEWaypMKB_aBaVNhzN7UAJ4S3MpZ-r4Bju1TwMTrsFEXGF2TpYIzZyGoIpXf-Dz__wVWVV9UEI131wAx6Km7imr8zQa2eZIr21hsDm5_vQyuFw9PEMNms70_P7X4cc9HvBnpfIoDNtH4dpvQtJ7dvop2NMkMm899UbKnnPh_Be6UD6kX_0d5UdymBid9YHZTO-c-oet_0m00?></g></svg> |