Logs

Date: 18/03/25

Date 01/04/25

Date 02/04/25

Microsoft Azure Setup

After researching Azure's high-availability reference architecture (App Gateway, VNet, Private Link, WAF), we opted for the simpler App Service + Azure SQL pattern—enough for our needs without unnecessary complexity. img1

For a cloud-based WebApp with a database it seems to just be; Azure App Service → Hosts our C# WebApp (.NET-9), Azure Database → Cloud-based relational database, App Service → DB Connection → Securely connect the WebApp to the database

Sprint-1 (Local Development):

  1. Reuben codes the C# WebApp locally temporarily using SQLite.
  2. I set up an Azure SQL database and connection locally.
  3. Mock Data Local Testing.

Sprint-2+ (Cloud-Integration, Improvements & Features)::

  1. Push the app to Azure.
  2. Configure CI/CD deployment.
  3. Add data-analytics.
  4. Improve performance & security.

Very simple; Search for "Resource Groups" on Azure Portal, Click Create, Name it, Pick a Region, Click Review+Create. img2

Created Resource Group, assigned Reuben Contributor via IAM, spun up Azure SQL (Free Tier), and later added our custom domain via CNAME/TXT verification.

Provisioned a single Azure SQL Free-Tier database (10 DBs, 100K vCore-seconds, 32 GB data + backup) inside our Resource Group; created a new server using Microsoft Entra-only authentication (not supported on Free Tier), enabled public access and allowed Azure services, whitelisted our dev IP, skipped ledger diagnostics, noted the future need for a managed identity, and set the collation to Latin1_General_100_CI_AS_SC_UTF8 for broad character support (lots of languages). Note: 5.50$ per-month after the free trial. img3

Server is container managing authentication/security. The App-service runs our .Net-App, has a Managed Identity, secure but negates need of username/password.

The next steps require:

  1. Enable a managed identity on app service: In the App-Service, turn on System-assigned Managed Identity in Settings/Identity.
  2. Grant Access for App: Go to SQL Server, under Active Directory admin, enable Entra-authentication. Then run in the Query-Editor for the database:
    CREATE USER [your-app-service-name] FROM EXTERNAL PROVIDER;
    ALTER ROLE db_owner ADD MEMBER [your-app-service-name];
  3. Connect .NET:
  1. Deployment of the .NET into the App Service: Make app service, realised later don't make it private as this forgets the Github deployment isn't within Azure, so connect to Github Repository and enable pre-configured CI!!!

Date 03/04/25

Create an Azure SQL Database using the REST API?: https://learn.microsoft.com/en-us/rest/api/sql/rest-api-sql-create-or-update-database
Configure continuous deployment to Azure App Service?: https://learn.microsoft.com/en-us/azure/app-service/deploy-continuous-deployment?tabs=github%2Cgithubactions#configure-the-deployment-source
Needed to re-add IP-address for Query Editor Acces?:
img4 img5
Note: Don't leave Query Editor with an unsaved complex script as it will be lost.
Merged everything previous and hopefully it is now connected to the DB. CI working well - automatically re-deploying with the pushed changes!!!

Testing DB-connection in Program.cs:
Not working! Alter roles?
img6
Free Plan does not include Managed Identity: need to switch to SQL authentication!!! code2 cmd: dotnet remove package Azure.Identity, dotnet clean, dotnet build
Removed identity use in Program.cs and appsettings.json: code3 Checking LyricalUser in the DB: code4

Logging:

Program.cs Logging not working?!

app.MapGet works!

Date 04/04/25

Logging works, no Database connection:

img7
CloudSAc3a0ae0e was auto-generated — turns out it's the master DB login.

Good. We don't need this in app.settings then: code7

Setting up the Database

I granted permissions to LyricalUser and made a quick table! Very Happy.
img9 Injection: We may need to stop injection attacks if we are using simple account username/password ~ may not be needed.
img10

TRUNCATE TABLE table_name is one way to reset identity id count, but it does also delete everything, another way would be to add a new_id column then delete the old one and rename the new one.

img11

System Idea 1 set up: Words, Sentences, and a linking sentence_word table.
song → paragraph (group_id) → sentence (id and position) → words (id and position)
Sentences + words stored once each - keeps things clean. sentence_word turns a song into an ordered ID map. Feels very systematic. Translation-ready: English, Russian, Deutsch, Español, Français. Reuben can add more if needed - columns are extendable.
Designed with Reuben's flow in mind - checks if sentence/word exists. If not, adds it + links by ID. Since there's no deletion, IDs can just be max+1 - or if needed, remove IDENTITY column and set manually (though that logic must be watertight).
Really solid DB design exercise. Rewarding. Feel like my relational DB intuition is a lot sharper now.

And I think now the next main phase of the project will be writing a load of C#/SQL, slightly more Reuben's part. After that we can start mock testing and after I want to try set up simple Data Anlysis.

Date 11/04/25

Have collaborated on how the DataBase works so that the code can be written accordingly. Realised that if we stick the Connection String back into appsettings.json then we don't need to redeploy the app every time!
FYI: using mock-song https://lyricstranslate.com/en/pod-rakitoju-zelenoj-%D0%BF%D0%BE%D0%B4-%D1%80%D0%B0%D0%BA%D0%B8%D1%82%D0%BE%D1%8E-%D0%B7%D0%B5%D0%BB%D1%91%D0%BD%D0%BE%D0%B9-under-green-willow.html

Date 29-30/04/25

code8

Tried something clever to fill out sentence_words automatically but despite new SQL-knowledge it didn't work and I had to do it manually:
img12 code9

Also added an Og column for the song's orginal lyrics in whatever language, serving as the original lyrics which can be translated into whatever choice desired.
Here I better understood defining the table column definitions in C#; though I would like more practice in future.

So need to warn anyone attempting to try it.
Useful DNS checking: https://www.whatsmydns.net/#CNAME/