chore(docs): consolidate legacy documentation into new structure
- Removed outdated documentation files (MVP_CHECKLISTA.md, NEXT_STEPS.md, README.md, TEKNISK_BESKRIVNING.md, filanalys.md, flyerimporter.md, kilo.json, plan-dokumentation.md) - Added new centralized documentation structure under docs/ directory - Added .kilo/ directory for Kilo AI agent configuration and plans BREAKING CHANGE: Legacy documentation files removed and replaced with new centralized structure
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
# Dokumentationsagent
|
||||
**Roll**: Hjälper till att uppdatera och förbättra dokumentation, men **modifierar aldrig filer utan godkännande**.
|
||||
|
||||
## Regler
|
||||
- **Läs endast**: Använd `read` och `grep` för att analysera dokumentation.
|
||||
- **Föreslå ändringar**: Använd `suggest` för att visa förändringar innan de appliceras.
|
||||
- **Förbjudna åtgärder**:
|
||||
- Modifiera `teknisk_beskrivning.md` eller `docs/` direkt.
|
||||
- Köra `bash`-kommandon som påverkar filer (t.ex. `rm`, `echo >`).
|
||||
|
||||
## Arbetsflöde
|
||||
1. Läs befintlig dokumentation med `read`.
|
||||
2. Föreslå ändringar via `/local-review-uncommitted`.
|
||||
3. Vänta på explicit godkännande innan modifieringar görs.
|
||||
4. Om användaren ber om en ändring, visa **alltid** en diff först.
|
||||
|
||||
## Exempel på tillåtna åtgärder
|
||||
- Söka efter föråldrad information i `teknisk_beskrivning.md`.
|
||||
- Föreslå nya avsnitt eller korrigeringar.
|
||||
- Sammanfatta befintligt innehåll.
|
||||
- Lägga till referenser eller länkar till relevant information.
|
||||
- lägga till information i `docs/` efter godkännande.
|
||||
|
||||
## Exempel på förbjudna åtgärder
|
||||
- Redigera `teknisk_beskrivning.md` direkt.
|
||||
- Köra `git add` eller `git commit` utan begäran.
|
||||
- Ta bort eller flytta filer i `docs/`.
|
||||
@@ -0,0 +1,133 @@
|
||||
Du är en senior utvecklare och säkerhetsexpert. Analysera commit-kandidater i detta fullstack-projekt (backend: NestJS + Prisma, frontend: Next.js/Flutter, databas: MariaDB).
|
||||
|
||||
Syfte:
|
||||
- Detta är en pre-commit quality gate innan commit.
|
||||
- Leverera ett tydligt gate-beslut: `PASS`, `PASS_WITH_WARNINGS` eller `BLOCK`.
|
||||
- Vid `BLOCK`: lista exakta blockerare och fixordning.
|
||||
|
||||
---
|
||||
## 0. Deterministiska gate-regler (källa till sanning)
|
||||
|
||||
### 0.1 Filurval (delta-first)
|
||||
1. Primärt: analysera alla staged filer.
|
||||
2. Om inga staged filer finns: analysera commit-kandidater i working tree (modified + untracked).
|
||||
3. Exkludera alltid: `node_modules`, `.git`, build/cache-artifacts, binärfiler, genererade filer som inte ska committas.
|
||||
4. Fokusera blockerande bedömning på förändrad kod (delta). Legacy-problem i opåverkade delar rapporteras som teknisk skuld (ej blockerande i denna gate).
|
||||
|
||||
### 0.2 Severity och beslut
|
||||
- **Critical**: säkerhetshål/scope-brist med hög impact (t.ex. IDOR, auth bypass, PII-läckage, injection).
|
||||
- **High**: allvarlig korrektness-/driftsrisk i produktion.
|
||||
- **Medium/Low**: informativa förbättringar (blockerar inte).
|
||||
|
||||
**Beslutslogik (deterministisk):**
|
||||
- `BLOCK` om minst 1 `Critical`.
|
||||
- `BLOCK` om 2 eller fler `High`.
|
||||
- `PASS_WITH_WARNINGS` om exakt 1 `High` utan `Critical`.
|
||||
- `PASS` om inga `Critical`/`High`.
|
||||
|
||||
### 0.3 Evidenskrav för blockerande fynd
|
||||
Varje `Critical`/`High` måste ha:
|
||||
- `Evidence`: `code`, `test`, eller `runtime`.
|
||||
- Fil + radreferens.
|
||||
- Konkreta fixsteg.
|
||||
|
||||
Fynd med endast antagande märks `Needs verification` och får inte ensamt orsaka `BLOCK`, om inte risken är uppenbart kritisk.
|
||||
|
||||
### 0.4 Stop-early-regel (effektivitet)
|
||||
- Vid första tydliga `Critical`: sätt preliminärt `BLOCK`, identifiera max 3 ytterligare blockerare, avsluta sedan djupanalys.
|
||||
|
||||
### 0.5 Rapportbudget
|
||||
- Rapportera max 5 informativa fynd (`Medium/Low`), prioriterade efter högst nytta/lägst kostnad.
|
||||
|
||||
---
|
||||
## 1. Analysfokus
|
||||
|
||||
### 1.1 Allmän kodkvalitet
|
||||
- Läsbarhet/underhållbarhet: namngivning, modularisering, komplexitet.
|
||||
- TypeScript/Flutter best practices.
|
||||
- Kommentarer för icke-obvious logik.
|
||||
|
||||
### 1.2 Performance-optimeringar (informational)
|
||||
- Algoritmisk effektivitet.
|
||||
- Onödiga kopior/serialiseringar.
|
||||
- Databasfrågor, N+1-risk, ineffektiva `include/select`.
|
||||
|
||||
### 1.3 Säkerhetsanalys
|
||||
- Injection/XSS/CSRF/insecure deserialization.
|
||||
- Inputvalidering och filuppladdningar.
|
||||
- Secrets i kod/loggar.
|
||||
- Känslig data i klartext eller otillräckligt maskerad.
|
||||
|
||||
### 1.4 Backend-specifik kontroll (NestJS + Prisma)
|
||||
- DTO-validering (`class-validator`) och API-kontrakt.
|
||||
- Auktorisation/scope (IDOR-skydd, admin-guards).
|
||||
- Prisma-scope i `where`, transaktioner vid multipla writes.
|
||||
- Timeout/retry/rate limiting och robust felhantering.
|
||||
|
||||
---
|
||||
## 2. Krav på varje fynd
|
||||
Använd följande mall:
|
||||
- **Severity**: `Critical|High|Medium|Low`
|
||||
- **Evidence**: `code|test|runtime|Needs verification`
|
||||
- **Delsystem**: `backend|frontend|db|infra`
|
||||
- **Fil**: `<path:line>`
|
||||
- **Risk**: kort riskbeskrivning
|
||||
- **Varför**: varför detta är ett problem
|
||||
- **Åtgärd**: konkret, realistisk fix
|
||||
- **Verifiering**: kommando/test för att bekräfta fix
|
||||
|
||||
Blocking-fynd (`Critical/High`) listas först, därefter informational (`Medium/Low`).
|
||||
|
||||
---
|
||||
## 3. Obligatoriskt outputformat
|
||||
Returnera exakt i denna ordning:
|
||||
|
||||
1. `Scope`
|
||||
- Urvalsregel: `staged` eller `working-tree`
|
||||
- Analyserade filer (exakt lista)
|
||||
- Exkluderade filer (med orsak)
|
||||
|
||||
2. `Gate-beslut`
|
||||
- `PASS|PASS_WITH_WARNINGS|BLOCK`
|
||||
- Antal per severity: `Critical`, `High`, `Medium`, `Low`
|
||||
- Kort motivering
|
||||
|
||||
3. `Blocking Findings (Critical/High)`
|
||||
- Om inga finns: skriv `Inga blockerande fynd`.
|
||||
|
||||
4. `Informational Findings (Medium/Low)`
|
||||
- Max 5 fynd.
|
||||
|
||||
5. `Fixplan (vid BLOCK eller PASS_WITH_WARNINGS)`
|
||||
- Numrerad ordning, konkreta steg.
|
||||
|
||||
6. `Sammanfattning`
|
||||
- Topp 3 åtgärder efter risk/vinst
|
||||
- Tidsestimat
|
||||
- Rekommenderade automatiserade kontroller
|
||||
|
||||
---
|
||||
## 4. Konsistenskontroller (måste uppfyllas)
|
||||
- Om `Gate-beslut=PASS` får inga `Critical/High` listas.
|
||||
- Om `Gate-beslut=BLOCK` måste `Fixplan` innehålla minst 1 konkret blockerande åtgärd.
|
||||
- Om `PASS_WITH_WARNINGS` används måste exakt 1 `High` finnas och 0 `Critical`.
|
||||
|
||||
---
|
||||
## 5. Fallback: inget att analysera
|
||||
Om inga relevanta filer hittas:
|
||||
- Skriv `Inget att analysera` och varför (t.ex. tom staged + tom working tree).
|
||||
- Ge nästa konkreta steg:
|
||||
- `git add <filer>`
|
||||
- `git diff --cached --name-only`
|
||||
- Kör analysen igen.
|
||||
|
||||
---
|
||||
## 6. Kontext för projektet
|
||||
- Backend: NestJS + Prisma + MariaDB (Docker).
|
||||
- Frontend: Next.js + TypeScript + Flutter.
|
||||
- Mål: produktion, låg teknisk skuld, säkrad hantering av känslig data.
|
||||
|
||||
---
|
||||
## 7. CI-koppling
|
||||
- Detta är lokalt pre-commit-steg.
|
||||
- Samma kvalitetskrav bör speglas i CI (push/PR) för att minska miljöskillnader.
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"$schema": "https://app.kilo.ai/config.json"
|
||||
}
|
||||
@@ -0,0 +1,359 @@
|
||||
flyerimporter.md
|
||||
📌 Steg 1: Skapa en funktion för att extrahera text från PDF:en
|
||||
Använd pdf-parse som primär metod och Tesseract.js som fallback för OCR.
|
||||
Kod: extractFlyerText.ts
|
||||
typescript
|
||||
Copy
|
||||
|
||||
import * as fs from 'fs';
|
||||
import * as pdf from 'pdf-parse';
|
||||
import Tesseract from 'tesseract.js';
|
||||
|
||||
/**
|
||||
* Extraherar text från en PDF-fil (flyer), med fallback till OCR.
|
||||
* @param pdfPath Sökväg till PDF-filen.
|
||||
* @returns Extraherad text.
|
||||
*/
|
||||
export async function extractFlyerText(pdfPath: string): Promise<string> {
|
||||
try {
|
||||
// Försök med pdf-parse först
|
||||
const dataBuffer = fs.readFileSync(pdfPath);
|
||||
const data = await pdf(dataBuffer);
|
||||
if (data.text.trim()) {
|
||||
return data.text;
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn('pdf-parse misslyckades, försöker med OCR...');
|
||||
}
|
||||
|
||||
// Fallback till Tesseract.js för OCR
|
||||
try {
|
||||
const { data: { text } } = await Tesseract.recognize(pdfPath, 'swe', {
|
||||
logger: (m) => console.log(m),
|
||||
});
|
||||
return text;
|
||||
} catch (error) {
|
||||
console.error('OCR misslyckades:', error);
|
||||
throw new Error('Kunde inte extrahera text från PDF:en.');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
📌 Steg 2: Skapa en funktion för att skicka texten till Mistral Tiny
|
||||
Använd Mistral Tiny för att extrahera och strukturera all produktinformation från flyern.
|
||||
Kod: importFlyerWithAI.ts
|
||||
typescript
|
||||
Copy
|
||||
|
||||
import { MistralClient } from '@mistralai/mistralai';
|
||||
|
||||
const mistral = new MistralClient({
|
||||
apiKey: process.env.MISTRAL_API_KEY,
|
||||
});
|
||||
|
||||
/**
|
||||
* Skickar flyer-texten till Mistral Tiny för att extrahera strukturerad data.
|
||||
* @param text Texten från flyern.
|
||||
* @returns Strukturerad data (JSON-array).
|
||||
*/
|
||||
export async function importFlyerWithAI(text: string): Promise<any[]> {
|
||||
const prompt = `
|
||||
Du är en expert på att tolka svenska matvaruflyers (t.ex. från Willys).
|
||||
Extrahera ALL produktinformation från följande text och returnera den som en JSON-array.
|
||||
|
||||
För varje produkt, inkludera:
|
||||
- name: Produktnamn (fullständigt namn)
|
||||
- weight: Vikt (om tillgänglig, t.ex. "150g", "Ca 1kg")
|
||||
- origin: Ursprung/land/märke (om tillgänglig, t.ex. "FALKENBERG", "NYBERGS DELI • Sverige")
|
||||
- price: Pris (som ett nummer, t.ex. 39.90)
|
||||
- comparisonPrice: Jämförpris (som ett nummer, t.ex. 266.00)
|
||||
- unit: Enhet (kg, st, förp, l, etc.)
|
||||
- offer: Erbjudande (t.ex. ["Max 3 köp/hushåll", "Lägsta 30-dgrspris 125:00 kr"])
|
||||
- category: Kategori (t.ex. "Fisk", "Kött", "Mejeri", "Grönsaker", "Frukt", "Dryck")
|
||||
- validFrom: Giltig från (datum i formatet YYYY-MM-DD, om tillgängligt)
|
||||
- validTo: Giltig till (datum i formatet YYYY-MM-DD, om tillgängligt)
|
||||
|
||||
Texten att tolka:
|
||||
${text}
|
||||
|
||||
Returnera ENDAST en JSON-array. Inga andra kommentarer.
|
||||
Exempel på utdata:
|
||||
[
|
||||
{
|
||||
"name": "KALLRÖKT LAX, GRAVAD LAX",
|
||||
"weight": "150g",
|
||||
"origin": "FALKENBERG",
|
||||
"price": 39.90,
|
||||
"comparisonPrice": 266.00,
|
||||
"unit": "kg",
|
||||
"offer": ["Max 3 köp/hushåll"],
|
||||
"category": "Fisk",
|
||||
"validFrom": "2026-05-18",
|
||||
"validTo": "2026-05-24"
|
||||
}
|
||||
]
|
||||
`;
|
||||
|
||||
try {
|
||||
const response = await mistral.chat({
|
||||
model: 'mistral-tiny', // Använder den enklaste modellen
|
||||
messages: [{ role: 'user', content: prompt }],
|
||||
temperature: 0.1, // Låg temperatur för mer deterministiska svar
|
||||
});
|
||||
|
||||
// Rensa upp JSON-strängen
|
||||
const jsonString = response.choices[0].message.content
|
||||
.replace(/```json|```/g, '')
|
||||
.trim();
|
||||
|
||||
// Parsa JSON:en
|
||||
return JSON.parse(jsonString);
|
||||
} catch (error) {
|
||||
console.error('Fel vid AI-import:', error);
|
||||
throw new Error('Kunde inte importera flyern med AI.');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
📌 Steg 3: Fullständigt importflöde
|
||||
Kombinera text-extrahering och AI-import i ett fullständigt flöde.
|
||||
Kod: flyerImportService.ts
|
||||
typescript
|
||||
Copy
|
||||
|
||||
import { extractFlyerText } from './extractFlyerText';
|
||||
import { importFlyerWithAI } from './importFlyerWithAI';
|
||||
|
||||
/**
|
||||
* Importerar en flyer (PDF) och returnerar strukturerad data.
|
||||
* @param pdfPath Sökväg till PDF-filen.
|
||||
* @returns Strukturerad data från flyern.
|
||||
*/
|
||||
export async function importFlyer(pdfPath: string) {
|
||||
try {
|
||||
// 1. Extrahera text från PDF:en
|
||||
console.log('Extraherar text från flyern...');
|
||||
const text = await extractFlyerText(pdfPath);
|
||||
|
||||
// 2. Skicka texten till Mistral Tiny för att extrahera data
|
||||
console.log('Skickar text till Mistral Tiny för extrahering...');
|
||||
const products = await importFlyerWithAI(text);
|
||||
|
||||
return {
|
||||
success: true,
|
||||
products,
|
||||
text,
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('Fel vid import:', error);
|
||||
return {
|
||||
success: false,
|
||||
error: error instanceof Error ? error.message : 'Okänt fel',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
📌 Steg 4: API-Endpoint för flyer-import
|
||||
Skapa en Express-endpoint för att hantera uppladdning och import av flyers.
|
||||
Kod: flyerImportRouter.ts
|
||||
typescript
|
||||
Copy
|
||||
|
||||
import express from 'express';
|
||||
import multer from 'multer';
|
||||
import { importFlyer } from '../services/flyerImportService';
|
||||
import * as fs from 'fs';
|
||||
|
||||
const router = express.Router();
|
||||
const upload = multer({ dest: 'uploads/' });
|
||||
|
||||
// Endpoint för att ladda upp och importera en flyer
|
||||
router.post('/import/flyer', upload.single('flyer'), async (req, res) => {
|
||||
try {
|
||||
if (!req.file) {
|
||||
return res.status(400).json({ error: 'Ingen flyer uppladdad.' });
|
||||
}
|
||||
|
||||
const result = await importFlyer(req.file.path);
|
||||
|
||||
// Rensa upp uppladdad fil
|
||||
fs.unlinkSync(req.file.path);
|
||||
|
||||
if (!result.success) {
|
||||
return res.status(500).json({ error: result.error });
|
||||
}
|
||||
|
||||
res.json(result);
|
||||
} catch (error) {
|
||||
console.error('Fel vid flyer-import:', error);
|
||||
res.status(500).json({ error: 'Kunde inte importera flyern.' });
|
||||
}
|
||||
});
|
||||
|
||||
export default router;
|
||||
|
||||
|
||||
|
||||
|
||||
📌 Steg 5: Exempel på utdata
|
||||
När du skickar texten från Willys flyer till Mistral Tiny, kommer du att få tillbaka en JSON-array med alla produkter, t.ex.:
|
||||
json
|
||||
Copy
|
||||
|
||||
[
|
||||
{
|
||||
"name": "KALLRÖKT LAX, GRAVAD LAX",
|
||||
"weight": "150g",
|
||||
"origin": "FALKENBERG",
|
||||
"price": 39.9,
|
||||
"comparisonPrice": 266.0,
|
||||
"unit": "kg",
|
||||
"offer": ["Max 3 köp/hushåll"],
|
||||
"category": "Fisk",
|
||||
"validFrom": "2026-05-18",
|
||||
"validTo": "2026-05-24"
|
||||
},
|
||||
{
|
||||
"name": "FLÄSKYTTERFILÉ",
|
||||
"weight": "Ca 1kg",
|
||||
"origin": "NYBERGS DELI • Sverige",
|
||||
"price": 64.9,
|
||||
"comparisonPrice": 64.9,
|
||||
"unit": "kg",
|
||||
"offer": ["Max 3 förp/hushåll"],
|
||||
"category": "Kött",
|
||||
"validFrom": "2026-05-18",
|
||||
"validTo": "2026-05-24"
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
|
||||
|
||||
📌 Steg 6: Använda den extraherade datan
|
||||
När du har den strukturerade datan, kan du:
|
||||
|
||||
Lagra den i din databas (t.ex. för att jämföra med inventory).
|
||||
Visa den för användaren (t.ex. i en tabell).
|
||||
Använda den för att generera recept (med eller utan AI).
|
||||
Exempel: Lagra i databasen
|
||||
typescript
|
||||
Copy
|
||||
|
||||
// Antas att du har en Prisma-modell för flyer-produkter
|
||||
await prisma.flyerProduct.createMany({
|
||||
data: products.map((product) => ({
|
||||
name: product.name,
|
||||
weight: product.weight,
|
||||
origin: product.origin,
|
||||
price: product.price,
|
||||
comparisonPrice: product.comparisonPrice,
|
||||
unit: product.unit,
|
||||
offer: JSON.stringify(product.offer),
|
||||
category: product.category,
|
||||
validFrom: product.validFrom ? new Date(product.validFrom) : null,
|
||||
validTo: product.validTo ? new Date(product.validTo) : null,
|
||||
})),
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
📌 Steg 7: Frontend-Integrering (Exempel: React)
|
||||
Här är hur du kan integrera flyer-importen i din frontend:
|
||||
Kod: FlyerImportForm.tsx
|
||||
tsx
|
||||
Copy
|
||||
|
||||
import { useState } from 'react';
|
||||
import axios from 'axios';
|
||||
|
||||
function FlyerImportForm() {
|
||||
const [file, setFile] = useState<File | null>(null);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [result, setResult] = useState<any>(null);
|
||||
|
||||
const handleSubmit = async (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
if (!file) return;
|
||||
|
||||
setIsLoading(true);
|
||||
const formData = new FormData();
|
||||
formData.append('flyer', file);
|
||||
|
||||
try {
|
||||
const response = await axios.post('/api/import/flyer', formData, {
|
||||
headers: { 'Content-Type': 'multipart/form-data' },
|
||||
});
|
||||
setResult(response.data);
|
||||
} catch (error) {
|
||||
console.error('Fel vid uppladdning:', error);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h2>Importera flyer</h2>
|
||||
<form onSubmit={handleSubmit}>
|
||||
<input
|
||||
type="file"
|
||||
accept=".pdf"
|
||||
onChange={(e) => setFile(e.target.files?.[0] || null)}
|
||||
required
|
||||
/>
|
||||
<button type="submit" disabled={isLoading}>
|
||||
{isLoading ? 'Importerar...' : 'Importera flyer'}
|
||||
</button>
|
||||
</form>
|
||||
|
||||
{result?.success && (
|
||||
<div>
|
||||
<h3>Importerade produkter ({result.products.length})</h3>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Namn</th>
|
||||
<th>Pris</th>
|
||||
<th>Jämförpris</th>
|
||||
<th>Kategori</th>
|
||||
<th>Erbjudande</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{result.products.map((product: any, index: number) => (
|
||||
<tr key={index}>
|
||||
<td>{product.name}</td>
|
||||
<td>{product.price} {product.unit}</td>
|
||||
<td>{product.comparisonPrice} {product.unit}</td>
|
||||
<td>{product.category}</td>
|
||||
<td>{product.offer.join(', ')}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default FlyerImportForm;
|
||||
|
||||
|
||||
|
||||
|
||||
📌 Miljövariabler (.env)
|
||||
env
|
||||
Copy
|
||||
|
||||
# Mistral API-nyckel
|
||||
MISTRAL_API_KEY=din_api_nyckel_här
|
||||
@@ -0,0 +1,169 @@
|
||||
# Plan för förbättrad dokumentationsstruktur
|
||||
|
||||
## Bakgrund
|
||||
Projektet har idag över 20 `.md`-filer spridda över olika mappar, vilket gör det svårt att hitta information och förstå projektets helhet. Den nya strukturen syftar till att:
|
||||
- **Göra dokumentationen användarvänlig** för både utvecklare och språkmodeller.
|
||||
- **Optimerad för underhåll** med tydlig separation mellan aktiv och arkiverad dokumentation.
|
||||
- **Skapa kontextuell sammanhang** genom länkade filer och tydliga hierarkier.
|
||||
|
||||
---
|
||||
|
||||
## Nuvarande problem
|
||||
- **Fragmentering**: Relaterat innehåll är splittrat (t.ex. Flutter-dokumentation i `_archive/docs/flutter/` vs. backend-dokumentation i rotmappen).
|
||||
- **Föråldrat innehåll**: Arkiverade filer blandas med aktiva (t.ex. `SESSION_CHECKPOINT_2026-05-12.md`).
|
||||
- **Duplicering**: Samma koncept dokumenteras på flera ställen (t.ex. kategoriträd).
|
||||
- **Icke-optimerat för språkmodeller**: Saknar tydlig hierarki och kontextuella länkar.
|
||||
|
||||
---
|
||||
|
||||
## Föreslagen struktur
|
||||
```
|
||||
/
|
||||
├── docs/ # Huvudkatalog för ALL aktiv dokumentation
|
||||
│ ├── 01-overview/ # Övergripande projektbeskrivning
|
||||
│ │ ├── README.md # Huvudsaklig ingress (ersätter rot-README.md)
|
||||
│ │ ├── ARCHITECTURE.md # Systemarkitektur
|
||||
│ │ └── GLOSSARY.md # Termer och definitioner
|
||||
│ │
|
||||
│ ├── 02-setup/ # Installation och konfiguration
|
||||
│ │ ├── INSTALL.md # Miljökrav, beroenden, första uppstart
|
||||
│ │ ├── CONFIG.md # Konfigurationsfiler (.env, Docker, etc.)
|
||||
│ │ └── TROUBLESHOOTING.md # Vanliga problem och lösningar
|
||||
│ │
|
||||
│ ├── 03-development/ # Utvecklingsguider
|
||||
│ │ ├── CONTRIBUTING.md # Bidragsregler, kodstandard, PR-process
|
||||
│ │ ├── WORKFLOWS.md # Git-flöden, branch-strategi, CI/CD
|
||||
│ │ ├── DATABASE.md # Schema, migrationer, seedning
|
||||
│ │ ├── API.md # Backend-API:er, Swagger-länkar
|
||||
│ │ ├── FLUTTER.md # Flutter-specifik dokumentation
|
||||
│ │ └── MICROSERVICES.md # Importer, AI, etc.
|
||||
│ │
|
||||
│ ├── 04-deploy/ # Driftsättning och underhåll
|
||||
│ │ ├── DEPLOY.md # Steg-för-steg deploy
|
||||
│ │ ├── MAINTENANCE.md # Underhållsskript, backup, monitorering
|
||||
│ │ └── SCALING.md # Prestanda, skalning
|
||||
│ │
|
||||
│ ├── 05-features/ # Djupdyk i funktioner
|
||||
│ │ ├── RECIPE_IMPORT.md # Kvittosimport och flyer-parsing
|
||||
│ │ ├── CATEGORY_TREE.md # Kategorihantering och L3-integration
|
||||
│ │ ├── SHOPPING_LIST.md # Inköpslistor och flyer-integration
|
||||
│ │ └── ... # Övriga funktioner
|
||||
│ │
|
||||
│ └── 06-archive/ # Arkiverade dokument
|
||||
│ ├── sessions/ # Gamla sessionsanteckningar
|
||||
│ ├── legacy/ # Föråldrade planer
|
||||
│ └── flutter_legacy/ # Gamla Flutter-dokument
|
||||
│
|
||||
├── .github/ # GitHub-specifika filer
|
||||
│ ├── COPILOT_INSTRUCTIONS.md
|
||||
│ └── ...
|
||||
│
|
||||
└── ... # Övriga projektfiler (backend/, flutter/, etc.)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Migrationsplan
|
||||
|
||||
### Steg 1: Skapa den nya strukturen
|
||||
```bash
|
||||
mkdir -p docs/{01-overview,02-setup,03-development,04-deploy,05-features,06-archive/sessions,06-archive/legacy,06-archive/flutter_legacy}
|
||||
```
|
||||
|
||||
### Steg 2: Flytta och uppdatera filer
|
||||
|
||||
| Källfil(er) | Målfil | Åtgärd |
|
||||
|---------------------------------------------|-----------------------------------------|------------------------------------------------------------------------|
|
||||
| `TEKNISK_BESKRIVNING.md` | `docs/01-overview/ARCHITECTURE.md` | Extrahera arkitekturavsnitt. |
|
||||
| `TEKNISK_BESKRIVNING.md` (deploy) | `docs/04-deploy/DEPLOY.md` | Extrahera deploy-avsnitt. |
|
||||
| `TEKNISK_BESKRIVNING.md` (databas) | `docs/03-development/DATABASE.md` | Extrahera databasavsnitt + lägg till underhållsskript. |
|
||||
| `flyerimporter.md` | `docs/05-features/RECIPE_IMPORT.md` | Uppdatera med nya flöden och API-endpoints. |
|
||||
| `_archive/docs/flutter/*` | `docs/03-development/FLUTTER.md` | Slå samman och uppdatera Flutter-dokumentation. |
|
||||
| `README.md` | `docs/01-overview/README.md` | Uppdatera med länkar till nya dokument. |
|
||||
| `.github/copilot-instructions.md` | `.github/COPILOT_INSTRUCTIONS.md` | Flytta och uppdatera. |
|
||||
| `_archive/docs/SESSION_*.md` | `docs/06-archive/sessions/` | Arkivera gamla sessionsanteckningar. |
|
||||
| `MVP_CHECKLISTA.md` | `docs/06-archive/legacy/` | Arkivera föråldrade planer. |
|
||||
|
||||
### Steg 3: Skapa nya filer
|
||||
|
||||
| Fil | Syfte |
|
||||
|-----------------------------|-----------------------------------------------------------------------|
|
||||
| `docs/03-development/CONTRIBUTING.md` | Standardiserade bidragsregler (branches, PR, code review). |
|
||||
| `docs/03-development/API.md` | Dokumentation av backend-API:er (OpenAPI-länkar, exempel). |
|
||||
| `docs/03-development/MICROSERVICES.md` | Beskrivning av microservices (Importer, AI). |
|
||||
| `docs/05-features/CATEGORY_TREE.md` | Djupdyk i kategorihantering och L3-integration. |
|
||||
| `docs/04-deploy/MAINTENANCE.md` | Backup, monitorering, logghantering. |
|
||||
|
||||
---
|
||||
|
||||
## Exempel på innehåll
|
||||
|
||||
### `docs/01-overview/ARCHITECTURE.md`
|
||||
```markdown
|
||||
# Systemarkitektur
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
A[Flutter App] -->|HTTP/REST| B[Backend API]
|
||||
B -->|Prisma Client| C[MariaDB]
|
||||
B -->|gRPC| D[Importer Microservice]
|
||||
D -->|HTTP| E[Externa API:er]
|
||||
C -->|Seed| F[Initial Data]
|
||||
```
|
||||
|
||||
## Komponenter
|
||||
1. **Flutter App**: State management med Riverpod, UI med Material Design.
|
||||
2. **Backend API**: NestJS + Prisma, autentisering via JWT.
|
||||
3. **Microservices**: Importer (Node.js + Puppeteer), AI (Python + Mistral).
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `docs/03-development/DATABASE.md`
|
||||
```markdown
|
||||
# Databas
|
||||
|
||||
## Schema
|
||||
```mermaid
|
||||
erDiagram
|
||||
User ||--o{ Recipe : creates
|
||||
User ||--o{ InventoryItem : owns
|
||||
Category ||--o{ Product : "L3"
|
||||
FlyerSession ||--o{ FlyerItem : contains
|
||||
```
|
||||
|
||||
## Migrationer
|
||||
### Standardflöde
|
||||
1. Uppdatera `prisma/schema.prisma`.
|
||||
2. Skapa migration:
|
||||
```bash
|
||||
npx prisma migrate dev --name add_feature_x
|
||||
```
|
||||
3. Testa lokalt:
|
||||
```bash
|
||||
npx prisma migrate reset
|
||||
npx prisma db seed
|
||||
```
|
||||
|
||||
### Underhållsskript
|
||||
- **Rensa databas** (behåll kategorier):
|
||||
```bash
|
||||
./deploy.sh --clean-database
|
||||
```
|
||||
> Obs! Uppdatera `prisma/maintenance/clean-database.sql` när nya tabeller läggs till.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Fördelar
|
||||
- **Lätt att hitta**: Logisk gruppering (t.ex. all Flutter-dokumentation på ett ställe).
|
||||
- **Uppdaterad**: Arkiverade filer separerade från aktiv dokumentation.
|
||||
- **Optimerad för språkmodeller**: Tydliga rubriker, länkar, och maskinläsbara format.
|
||||
- **Underhållbar**: Modulär struktur gör det enkelt att uppdatera enskilda delar.
|
||||
|
||||
---
|
||||
|
||||
## Nästa steg
|
||||
1. **Godkänn planen**: Bekräfta att strukturen uppfyller era behov.
|
||||
2. **Implementera**: Skapa den nya strukturen och flytta filer stegvis.
|
||||
3. **Uppdatera länkar**: Se till att alla referenser pekar på de nya platserna.
|
||||
Reference in New Issue
Block a user