← WikiPetersson

Lessons Learned – AI-assisterad webbutveckling

Samlat från BSL Hälsodashboard-projektet (maj 2026). Gäller generellt för projekt där man arbetar med AI-verktyg (Claude, Copilot m.fl.) mot .js/.html-filer.

1. AI-verktygets Edit-funktion trunkerar stora filer tystigt

Det här är den viktigaste lärdomen från projektet. När ett AI-verktyg ersätter ett stort kodblock via sin Edit-funktion kan filen trunkeras utan felmeddelande — den slutar mitt i ett uttryck och ser till synes normal ut.

Varningssignal: Filen är ovanligt kort jämfört med förväntat, eller webbläsaren visar inga grafer/komponenter alls trots att HTML ser rätt ut.

Regel: använd script för block större än ~30 rader

Om du ska infoga eller ersätta mer än ~30 rader kod, be AI:n skriva ett Python-script som gör jobbet istället för att använda Edit direkt:

# Exempel: läs fil, hitta markeringspunkt, skriv ny version
with open('halsa-joacim.js', 'rb') as f:
    content = f.read()

marker = b'// MARKERING HÄR'
pos = content.find(marker)
new_content = content[:pos] + new_block.encode() + content[pos + len(marker):]

with open('halsa-joacim.js', 'wb') as f:
    f.write(new_content)

Verifiera alltid efter stora ändringar

Tumregel: Avsluta aldrig en session direkt efter att AI:n gjort en stor redigering. Kör alltid en snabb verifiering först.

2. Syntaxkontroll för JavaScript

Node.js inbyggda syntaxkontroll hittar fel utan att köra koden:

node --check filnamn.js

Tyst = OK. Annars skrivs felnummer och rad ut. Kör detta rutinmässigt efter varje AI-assisterad ändring.


3. Single-canvas + knappar för multidimensionella diagram

Om du har ett diagram som visar en datadimension i taget (t.ex. en pulsson i taget) är det bättre med ett enda canvas-element och knappar som byter vy, jämfört med separata canvaser per kategori.

Fördelar:

Mönstret:

// 1. Hämta all data en gång, spara globalt
let zonRows = [];
async function loadZontrend(from, to) {
  zonRows = await sbFetch('dag_zon_v', `?datum=gte.${from}&datum=lte.${to}`);
  renderZon('vila');  // visa defaultzon
}

// 2. Rendera om vid knapptryck
function renderZon(zonKey) {
  if (chart) { chart.destroy(); chart = null; }
  const values = zonRows.map(r => r[zonKey]);
  // … bygg Chart.js-config …
}

// 3. Knapphändelser
document.querySelectorAll('#zon-btns .period-btn').forEach(btn => {
  btn.addEventListener('click', () => {
    document.querySelectorAll('#zon-btns .period-btn')
      .forEach(b => b.classList.remove('active'));
    btn.classList.add('active');
    renderZon(btn.dataset.zon);
  });
});

4. Asynkron laddning för tunga databasfrågor

En tung fråga (mot en stor vy eller tabell) ska inte blockera resten av sidan. Lägg den utanför Promise.all:

// Snabba frågor parallellt
await Promise.all([
  loadGraf1(from, to),
  loadGraf2(from, to),
  loadGraf3(from, to)
]);

// Tung fråga startar separat — blockerar inte ovan
loadDagZontrend(from, to);

Användaren ser resten av sidan direkt, den tunga grafen poppar in när den är klar.


5. Generated columns i SQL — uppdatera aldrig manuellt

Om en tabell har genererade kolumner (t.ex. datum beräknat från en timestamp) ska dessa aldrig sättas manuellt i INSERT/UPDATE. Databasen räknar ut dem automatiskt — ett försök att skriva till dem ger fel.

Dokumentera vilka kolumner som är generated i projekttabellen så det inte glöms bort.


6. Oregelbundet arbete – checklista vid sessionsslut

När man återvänder till ett projekt efter veckor eller månader är det lätt att tappa tråden. Gör detta rutinmässigt innan du stänger en session:

  1. Kör node --check på alla JS-filer du rört
  2. Öppna sidan i webbläsaren och verifiera att allt renderas
  3. Notera var du är och vad som återstår — berätta för AI:n om du vill att det sparas i minnet
  4. Committa till git (om du använder det) med en tydlig commit-kommentar

Senast uppdaterad: maj 2026 — BSL Hälsodashboard-projektet