Visar differenshistoriken för alla dokument-filer som har ändrats, i fallande ordning efter datum.
Jag använder detta för att kunna orientera mig i senaste förändringar över flera dimensioner av systemet. Fungerar som ett utökat "närminne".
**25/nov** - aktiverat mitt debug system för websocket-servern. All diagnostik skickas till [konsollen](/tool/console). Svårighet med webutveckling är flera nivåer av diagnostik som inte alltid är lätt tillgänglig. "Konsollen" är en plats för allt.
**26/nov** - 1) Installerat MariaDB manuellt eftersom jag behöver senaste "cutting edge" versionen för UUIDv7. 2) Gått igenom och avancerat konceptet för databasen. 3) Undersökt alternativ till Redis. KeyDB är bättre för mig. Har testat det.
**28/nov:**
Behöver bättre verktyg att handskas med all den programkod jag kommer skapa.
Ska prova Gitea. Syfte: översikt, revisionshistorik, lätt att återskapa ett projekt, samt enkel backup och lätt att strukturera projekt. Även lätt att skapa ärenden för ett projekt.
Överväger först Github igen. Men det har för hög tröskel givet mitt smala användningsområde. Tar för lång tid att bemästra. Fungerar bra i början, sedan får jag alltid krångel med det. LazyGit hjälper, men nej... Har för lite kunskap om Github och känner att jag ej har kontroll över systemet. Inte värt spendera mer tid på eftersom jag inte behöver all den komplexitet Github erbjuder.
Ska testa Gitea istället och kan då "self-host" den. Alltså köra den på min egen server. Den sägs ha enklare gränssnitt.
##
- Lösningen för realtids synk är inte helt genomtänkt.
- Kan jag inte strunta i separat tabell för realtids synk i databasen. Skulle kräva 2 insättningar för varje enskild insättning.
**Åtgärd 3**
- Använd embart Redis för realtids synk.
Använd inte Redis. Använd KeyDB istället.
- KeyDB har stöd för "tiered storage". Om RAM minnet visar sig begränsat så nyttjar den hårddisken. I KeyDB är den funktionen fri. Redis å andra sidan kräver "Enterprise".
- Med "tiered storage" räcker det med KeyDB för min realtidssynk-funktion. Behöver inte fallback i databasen.
- Om KeyDB innehåll raderas (server-omstart) laddar klienterna ner data direkt från databasen.
Användaren laddar ner all sin data eller vet klienten en tidpunkt från vilken den ska ladda ner från?
- Använd tidpunkt. Klienten vet senaste tidpunkt då den uppdaterade sin lokala databas.
- SELECT * FROM user_data WHERE modified_at > $client_latest_update.
- Det kräver ett nytt fält modified_at.
-
- starten för mk-datalink - den del som sparar klientens data.
- node js websocket server
- gjort den till 'systemd' service.
- definierat protokoll för klient-server kommunikation för mk-datalink
- uppdaterat certifikat, behöver lära mig automatisera det. Är inte svårt men strategin är att göra det manuellt och enbart automatisera när jag lärt mig grunderna, and annars är det svårare att lösa problem i framtiden om man inte förstår vad det är som automatiserats.
- fixat reverse proxy för nginx för websocket server.
- fixat test domän för sajten.
Test-sajt test finns [här](https://test.matkalkyl.dev) just nu i primitivt stadie.
Har de senaste dagarna undersökt krypto och huruvida Etherium-blockchain kan användas för något skoj. Det kommer inte prioriteras just nu men är öppen för kreativa idéer i framtiden. Krypto är ett "kanin-hål" man lätt kan falla ner i all oändlighet men det ska jag undvika.
Har misslyckats med balans och kontinuitet i min systemutveckling.
Har lyckats skapa rutin för mer variation i vardagen med motion etc, men har inte lyckats hålla det kontinuerligt mot andra saker som krävt uppmärksamhet. Måste förbättra bedömning och prioriteringsförmåga.
Ser att jag överlag lyckats tillräckligt bra med ordning på min lokala dator och servern så jag snabbt kan återuppta utveckling. Annars brukar det vara så att man inte kan förstå sitt eget system när man återvänder efter någon tid. Verkar som jag lyckats radera vanorna som ligger till grund för det.
Har lyckats skifta fokus till att tänka och analysera mer innan jag börjar programmera, men risk finns att hamna i "analys-paralys". Tänkande måste gå hand i hand med handlingskraft.
### MEAN-analys
#### Mål
(beskrivning av mål)
Kontinuerlig systemutveckling varje dag, balanserat med motion, rätt kost och rätt sömn.
Målet i sig självt är att bemästra kontinuitet och rutin.
#### Effekt
(vilken effekt som syns i verkligheten)
- Vakna upp samma tid varje dag.
- Definiera och följa samma morgonrutin varje dag.
- Avsluta dagen samma tid varje dag.
- Avsluta dagen med samma kvällsrutin varje dag.
- Planera datoranvändning på förhand.
#### Analys
(alla detaljer kring hur det ska genomföras i detalj)
#### Negation
(all kritik om varför det kommer misslyckas, and samt omarbetad ovanstående Mål, and Effekt och Analys för att svara mot den kritiken)
Vad är potentiella hinder och hur ska jag hantera dem.
##
Planera nyckel aspekter.
Koncept: Datalink, länk mellan klient och server. Mellanlager mellan databas och klient.
### Mål
Möjliggöra synkron kommunikation mellan server och klient. Synkron för att kunna garantera att innehåll levereras, och att det görs i turordning.
### Effekt
- En node js websocket server.
- En nginx reverse proxy för websocket.
- En js komponent för klienten för interaktion med server.
### Analys
#### Definiera ett protokoll för kommunikation.
| Field | Size (Bytes) | Description |
|-------------|--------------|-------------------------|
| Key | 2 | A 16-bit unsigned key. |
| Payload | Variable | The rest of the message.|
```
// Server
server.on('connection', (ws) => {
ws.on('message', (data) => {
if (Buffer.isBuffer(data)) {
const key = data.readUInt16BE(0); // Read the first 2 bytes as the key
const payload = data.slice(2); // Extract the payload
// ...
// Client
const socket = new WebSocket('ws://localhost:8080');
socket.binaryType = 'arraybuffer'; // WebSocket set to handle binary data
socket.onopen = () => {
const key = 42; // Example 2-byte key
const payload = new TextEncoder().encode('Hello, WebSocket!'); // Payload as Uint8Array
// Create ArrayBuffer for key + payload
const buffer = new ArrayBuffer(2 + payload.byteLength);
const view = new DataView(buffer);
view.setUint16(0, key); // Write the key (2 bytes)
new Uint8Array(buffer, 2).set(payload); // Write the payload after the key
socket.send(buffer); // Send the binary message
};
```
#### Definiera plugin system för hantering av data.
```
// Plugin registry
const plugins = {};
// Load plugins dynamically from the "plugins" directory
const pluginDir = path.join(__dirname, 'plugins');
fs.readdirSync(pluginDir).forEach((file) => {
const key = path.basename(file, '.js'); // Extract key from filename
plugins[key] = require(path.join(pluginDir, file)); // Load plugin
});
//...
if (plugins[key]) {
plugins[key](payload, ws); // Pass payload and WebSocket instance
} else if (plugins.default) {
plugins.default(message, ws);
```
##
Jag är nöjd med gårdagen. MEAN-modellen är en metod för kritiskt tänkande vid utveckling av komponenter. Jag var bekymrad över att jag kanske lagt ner tid på att ta fram MEAN-modellen med resultatet av en tjusig idé utan användning. Hej med viss justering visade den sig användbar. Den summerar, förfinar och ritualiserar min tankeprocess.
Igår var det databas: [Här är modulen för användardata](/decision/sys-db-user-data)
Idag ska jag göra samma process för komponent för realtids-synk mellan enheter.
[Här är modul för realtids-synk](/decision/mod-realtime-sync)
##
Lagra användarens data, möjliggöra och förhindra åtkomst av data.
**Effekt**
Omarbetad version
```
-- Ett datablock
{
row_uuid:UUIDv7,
user_id:RAND(INT),
data_state:TINYINT,
data_subtype:SMALLINT,
data:BLOB, -- regardless of binary or text content, choose BLOB.
}
```
**Analys/Applicering**
- Klient genererar UUIDv7.
- UUIDv7 ger tidsbaserade id.
- Server genererar användares ID vid konto-skapande.
- Om saknas: Klient laddar ner hela sin databas inom ett tidsspann och lagrar som lokal kopia.
- Klient CRUD på enskild rad via UUID.
- Databas registrerar datablockets status: insatt, uppdaterad, raderad.
- Klient kan sätta och söka på egen-definierad datatyp för datablock.
- UUIDv7 som primär nyckel gör klienten oberoende av servern i skapande av data och vi slipper komplicerad placeholder-lösningar för ID.
- Permissions-kontroll ska ingå då det faller i kategori "tillkomst av data" vilket är del av målet.
**Negation**
- Databasen ska inte se relationer mellan data. Bara CRUD aktiviteter. Är det uppnått?
- Försvårar den realtids-synk?
- Försvårar den permissions-kontroll och annat i kollaborativ miljö?
- Gör den mer än den ska och anpassar sig specifikt efter något? -
- `data_type` ogillas, varför ska databasen ha separat fält för klientens valda datatyper, kan du inte ta bort den. Nej. Det är del av struktur för tillgång av data, inte för association av data på server så som i JOIN aktiviteter, så målet med en "blind" databas är bevarat.
- Är alla kolumn-typer optimala.
- Är databasen optimal med hänsyn till innehållets form. ❌ Nej. Inte optimalt med en tabell för all data.
**Åtgärder**
- `data_type` borttaget.
- varje modul (plugin) registrerar sina data-typer och har egen tabell för sin data. Matlistan är en modul med en tabell, användar-inställningar är en annan modul med egen tabell.
- Vi har två typer av data. 1) Sådant som vi vill tillgå via tidsspann (ex. senaste registrerade värdena), 2) sådant som vi vill tillgå via användar-id (returnerar då all användarens data, and ex. alla matprodukter). Tabellerna kan då indexeras/optimeras efter åtkomst-typ, dvs på uuid (rad-id) eller userid. Flera fördelar finns.
- Varje modul har därför antingen eller både `tabell_[modul-id][a|b]`. Ex. table_1a, table_1b.
- Introducera data_subtype för att ge modul möjlighet till segmentering efter eget behov.
**Negation rond 2**
- Realtidssynk blir plugin, det är bra, håller sig utanför målet för denna modul. Dvs databasen anpassar sig inte särskilt efter synk. Den är samma för alla moduler.
- Bättre optimerat: En tabell på miljoner rader blir nu uppdelad i många tabeller. God databas-sed, underlättar indexering, and caching, and sökning etc.
- Alla tabeller är uniforma, enkelt och bra. Ingen särbehandling med modul-specifika kolumner. Klient lagrar specifik data i BLOBen och strukturerar på klientsidan. Databas på server bryr sig inte om specifik struktur.
- Bra: fortfarande CRUD.
[tip] Livstips: Liksom modulen-designen ovanför; känn dig själv och gör din sak väl och kompromissa med andra som förskjuter sitt ansvar åt ditt håll. Låt andra ta ansvar för sin egen måluppfyllelse och att hålla det inom sin egen sfär. Föregå med gott exempel och inspirera andra att
- Permissions-kontroll, hur ska du göra där?
- Hur göra med kryptering-versionen i kolaborativ miljö?
**Åtgärd rond 2**
Permission - en användare kan ge en eller flera användare tillgång till viss data.
Separat tabell:
```
table permissions
{
owner_id: INT,
subject_table: TINYINT,
data_subtype: SMALINT DEFAULT NULL,
from: DATETIME DEFAULT NULL,
to: DATETIME DEFAULT NULL,
read: BOOL,
write: BOOL,
users_granted: JSON
}
```
- Om from eller to är NULL, då ingen gräns i den riktningen.
- Om data_subtype
[Här
- Aktiva användares permissions-tabell kan läggas som ett kontroll-lager i Redis, med fallback på databas. Eller bättre: Redis csching av permissions-tabeller.
Krypteringen:
- Klient krypterar som vanligt om den vill. Databasen bryr sig inte om vad som lagras i BLOBen. Annan användare kan inte läsa den även om det delas.
- Kan göra separat asymmetrisk kryptering (public-key encryption)
Se där... Min strategi att lägga mycket tanke på databas verkar god.
>"Dåliga programmerare bekymrar sig över koden. Bra programmerare bekymrar sig över datastrukturer och deras relationer." (Linus Torvalds, skapare av Linux-kärnan och Git, översatt)
Är fortfarande i skedet att tänka ut och tänka om databasen.
Jag kommer använda MEAN-metoden jag framställde 11 nov, som tankesätt för definition av modulen.
**Mål**
Lagra användarens data, möjliggöra och förhindra åtkomst av data.
**Effekt**
Omarbetad version
```
-- Ett datablock
{
row_uuid:UUIDv7,
user_id:RAND(INT),
data_state:TINYINT,
data_subtype:SMALLINT,
data:BLOB, -- regardless of binary or text content, choose BLOB.
}
```
**Analys/Applicering**
- Klient genererar UUIDv7.
- UUIDv7 ger tidsbaserade id.
- Server genererar användares ID vid konto-skapande.
- Om saknas: Klient laddar ner hela sin databas inom ett tidsspann och lagrar som lokal kopia.
- Klient CRUD på enskild rad via UUID.
- Databas registrerar datablockets status: insatt, uppdaterad, raderad.
- Klient kan sätta och söka på egen-definierad datatyp för datablock.
- UUIDv7 som primär nyckel gör klienten oberoende av servern i skapande av data och vi slipper komplicerad placeholder-lösningar för ID.
- Permissions-kontroll ska ingå då det faller i kategori "tillkomst av data" vilket är del av målet.
**Negation**
- Databasen ska inte se relationer mellan data. Bara CRUD aktiviteter. Är det uppnått?
- Försvårar den realtids-synk?
- Försvårar den permissions-kontroll och annat i kollaborativ miljö?
- Gör den mer än den ska och anpassar sig specifikt efter något? -
- `data_type` ogillas, varför ska databasen ha separat fält för klientens valda datatyper, kan du inte ta bort den. Nej. Det är del av struktur för tillgång av data, inte för association av data på server så som i JOIN aktiviteter, så målet med en "blind" databas är bevarat.
- Är alla kolumn-typer optimala.
- Är databasen optimal med hänsyn till innehållets form. ❌ Nej. Inte optimalt med en tabell för all data.
**Åtgärder**
- `data_type` borttaget.
- varje modul (plugin) registrerar sina data-typer och har egen tabell för sin data. Matlistan är en modul med en tabell, användar-inställningar är en annan modul med egen tabell.
- Vi har två typer av data. 1) Sådant som vi vill tillgå via tidsspann (ex. senaste registrerade värdena), 2) sådant som vi vill tillgå via användar-id (returnerar då all användarens data, and ex. alla matprodukter). Tabellerna kan då indexeras/optimeras efter åtkomst-typ, dvs på uuid (rad-id) eller userid. Flera fördelar finns.
- Varje modul har därför antingen eller både `tabell_[modul-id][a|b]`. Ex. table_1a, table_1b.
- Introducera data_subtype för att ge modul möjlighet till segmentering efter eget behov.
**Negation rond 2**
- Realtidssynk blir plugin, det är bra, håller sig utanför målet för denna modul. Dvs databasen anpassar sig inte särskilt efter synk. Den är samma för alla moduler.
- Bättre optimerat: En tabell på miljoner rader blir nu uppdelad i många tabeller. God databas-sed, underlättar indexering, and caching, and sökning etc.
- Alla tabeller är uniforma, enkelt och bra. Ingen särbehandling med modul-specifika kolumner. Klient lagrar specifik data i BLOBen och strukturerar på klientsidan. Databas på server bryr sig inte om specifik struktur.
- Bra: fortfarande CRUD.
[tip] Livstips: Liksom modulen-designen ovanför; känn dig själv och gör din sak väl och kompromissa med andra som förskjuter sitt ansvar åt ditt håll. Låt andra ta ansvar för sin egen måluppfyllelse och att hålla det inom sin egen sfär. Föregå med gott exempel och inspirera andra att definiera sitt mål och själva hitta och utföra handlingar i den riktningen, men gör det inte åt dem.
- Permissions-kontroll, hur ska du göra där?
- Hur göra med kryptering-versionen i kolaborativ miljö?
**Åtgärd rond 2**
Permission - en användare kan ge en eller flera användare tillgång till viss data.
Separat tabell:
```
table permissions
{
owner_id: INT,
subject_table: TINYINT,
data_subtype: SMALINT DEFAULT NULL,
from: DATETIME DEFAULT NULL,
to: DATETIME DEFAULT NULL,
read: BOOL,
write: BOOL,
users_granted: JSON
}
```
- Om from eller to är NULL, då ingen gräns i den riktningen.
- Om data_subtype är NULL, då tillgång till alla typer.
- Aktiva användares permissions-tabell kan läggas som ett kontroll-lager i Redis, med fallback på databas. Eller bättre: Redis csching av permissions-tabeller.
Krypteringen:
- Klient krypterar som vanligt om den vill. Databasen bryr sig inte om vad som lagras i BLOBen. Annan användare kan inte läsa den även om det delas.
- Kan göra separat asymmetrisk kryptering (public-key encryption) för kolaboratov miljö (också på plugin-nivå).
##
[utforma databas](/plan/inquiry)
...
## 1 november
...
Ny vecka. Dagens teknikfokus längre ner.
[note] Varför är mitt fokus just nu så mycket på personlig utveckling? Kort svar: utan hälsa blir inte mycket gjort. Jag behöver göra personliga topp-val, och göra blixt-förändringar av dåliga vanor, parallellt med allt annat jag gör. Jag agerar proaktivt, för efter 40 litar jag inte på framtiden såvida jag själv inte tar kommandot. Långt svar: Därför att när du blir 40 ska du redan ha etablerat de bästa rutinerna och förhållningssättet livet. Du ska ha hittat de bästa lösningarna på allt från vardagliga saker till psykologi. Har du inte bestämt dig i basala ting vid det här laget så är det bäst att du skyndar dig. Det är vad jag gör: skyndar mig att ta mitt ansvar att bestämma mig för saker och ting - allt från personligt datorsystem, till skoinlägg, till livsfilosofi etc... Mellan 20-40 ska du experimentera med förhållningssätt och idéer. Efter 40 måste du ha bestämt dig för den bästa lösningen i alla frågor och i alla praktiska ting, så du kan börja förfina det och fördjupa dig i en livsriktning och därigenom uppleva din potential att utforma dig själv i bilden av den du verkligen vill vara om du fick välja (du både får och ska välja). Var inte öppen för allt en hel livstid där du hoppar från en sak till en annan, ständigt osäker och obeslutsam - det vill säga; en som tar dagen som den kommer, snarare än att sätta riktning för dagen, för livet. Välj en riktning, skärma av annat, och fördjupa dig i din valda livsriktning.
Denna gång ska jag utveckla metod för problemlösning (främst avseende it-system, men jag tar det sedan vidare). Kan inte gå enbart på känsla varje gång. All problemlösning kan omfattas av en generell metod. Hitta bästa tillvägagångssätt en gång för alltid.
💭 💡
Sådär... Jag har uppfunnit en ny "utvecklingsmodell" - alltså en framgångs-modell.
Den kallas MEAN - Mål, Effektivisering, Analys, Nytänk.
Jag inspirerades av den Japanska Lean-modellen som skapades av Toyota. Den är en metod för att effektivisera produktion genom att skala bort ovessentligheter.
Det engelska ordet "mean" används i uttrycket "Lean and Mean". I detta sammanhang betyder det första ordet "Lean" att man har skurit bort allt onödigt och fokuserar på det väsentliga, medan det andra ordet "Mean" innebär att man är tuff, bestämd och redo att agera snabbt och kraftfullt. Tillsammans förmedlar uttrycket idén om en slimmad, fokuserad och kraftfull enhet som är redo att nå sina mål utan onödiga hinder eller kostnader.
"Mean" betyder också elak. Min modell är elak och tuff. I steg 1-3 framställer du en lösning. Steg 4 är till för att elakt rasera den lösningen genom outside-the-box tänkande och djupt kritisk analys och ursinnigt ifrågasättande av **både** problemställning och lösning från steg 1-3. Steg 4 ifrågasätter både relevansen av målet i steg 1, och validiteten i lösningen från steg 2 och 3. Avsikten insteg 4 är att på god grund förkasta produkten från steg 1-3. Det är lätt att älska sina egna ambitioner och lösningar, men steg 4 ser till att du ifrågasätter båda och blir tuffare i ditt tänkande. En ny cykel av MEAN startas efter steg 4. I den nya cykeln måste 1-3 nu lösa kritiken från steg 4. När steg 1-3 vinner över steg 4, då är lösningen accepterad. Resultatet är något som är "Lean and Mean".
Första versionen av matkalkyl hade värdeorden "enkel, effektiv och exakt". För att verkligen ta projektet till nästa nivå, ska inte bara produkten vara "Lean and Mean". Mina utvecklings-metoder ska också vara "Lean and Mean". Det antar jag kommer ingjuta dessa värden - den energin - i produkten. Därtill ska jag applicera MEAN-metoden på min personliga utveckling så att jag förbättras i allt jag gör, vilket då ger mig bättre färdighet också i utveckling av denna sida.
Jag AI-genererade [en sammanfattning av MEAN-modellen](/inquiry/mean) som bara är preliminärt formulerad än så länge.
...
Ja, MEAN-modellen tar tuffare tag än min nuvarande metod som bygger på Dale Carnegies metod (som jag skrev om en tidigare dag i november).
Låt AI generera en version för personlig utveckling: [MEAN personlig utv.](/inquiry/mean-personal).
---
Föregående:
1 - Mestadels löst struktur för användarkonton, användardata, autentifikation.
2 - Bestämt typ av primär nyckel i databas för konton, och för användardata (UUIDv7). Det är ett beslut som är mycket svårt att ändra på sedan. Lösningen ska också hålla i 40 år, men kommer antagligen utan problem principiellt hålla i 80 eller mer, samt att databasen inte blir krånglig när den växer.
[caution] Se över hur en stor databas beter sig med UUIDv7. Mina tester visar att 400 000 rader inte är problem. Hur är det med miljoner rader? Hur beter sig indexering etc, hur kommer det optimeras för i framtiden inom databas-teknologi. Vilka inställningar i Databas kan motverka tänkbara problem. Viktigt inte måla in sig i ett hörn.
3 - Konstaterat att full anonymisering och kryptering öppnar för sårbarhet där servern lätt kan fyllas med skräp-data utan möjlighet att identifiera det (när användarens data är krypterad och därför ej synlig på servern). Därför skapar jag två versioner, en fri icke-krypterad, och möjligtvis senare kryptering som tilläggsfunktion mot betalning, eftersom betal-modell är det enda jag ser kan eliminera problemet (PoW är inte aktuellt). Den fria icke-krypterade versionen kommer prioriteras först, men grunden är lagd för att utöka med kryptering. Systemet ska vara en elastisk bas som kan utökas med mer funktioner, varav kryptering blir intressant då mer känslig data kanske lagrad via andra funktioner (säg en Att-göra-lista, eller personlig journal). Utöver det är kryptering en bra funktion för de som inte vill att deras data ska läcka om databasen stjäls, eller för de som helt enkelt vill hålla data privat. Där till, I den icke-krypterade versionen, kommer det inte finnas krav på att ange någon personlig information, precis som föregående version.
4 - Inga komplicerade operarioner, utan bara select, insert, update, delete. Detta eftersom klienten utformar databasens specifika struktur på klientsidan i IndexDB. Servern lagrar bara block med data. Den bryr sog om innehållet.
[caution] Se över att detta fortfarande gäller att inga andra operationer behövs.
Fokus:
1 - Behöver lösning för realtids-synsk mellan enheter. Kommer bli lågintensiv långvariga och lömska problem om det implementeras först när resten av systemet är på plats.
Scenario: anv. har 4 enheter. 1an och 2an direkt uppkopplade. 3an var uppkopplad men har internet-avbrott och kommer tillbaka senare. 4an har inte varit uppkopplad på länge och loggar in.
Mål: Anv. 1an uppdaterar data. Det synkas direkrekt med 2an. 3an redigerar data på sin uppkopplade enhet. 3an kommer tillbaka och får uppdateringen som 1an gjorde. 4an loggar in och får inledningsvis info om alla senaste uppdateringarna.
Hur lång är historiken över förändringar? Den är x lång. Om klient 4an loggat in tidigare än äldsta posten i historiken, måste klienten ladda ner alla aktuella data-block på nytt.
Behov:
I info om att uppdatering skett måste den uppdaterade infon bifogas. Annars måste större data-block laddas ner där uppdateringen ligger.
---
Om allt i ett system är moduler som utvecklas enskilt och har tydligt avgränsat ansvarsområde, då kan varje modul vid skapande genomgå samma utvecklings-bana; problemställning, analys, implementation, etc. Gör sådan utvecklings-bana gemensam för alla komponenter.
##
Nödvändiga teknik-logistiska aktiviteter.
Klient:
- väljer lösenord (P)
- genererar nyckel (DK) baserat i lösenordet (P), "Derived Key", enligt standard (ex. PBKDF2).
- Genererar PermaNonce (PN) baserat i P eller DK.
- generera uuidv7 som användar-id. (UID)
- uuid7 är primär identifierare, för enkelhet: användare anger ytterligare identifierar som användarnamn. (UNAME)
Sedan
```
{
“user_name“: UNAME,
"user_id": UID,
"perma_nonce": PN,
}
```
Skickas till server, server lägger in i tabellen "users".
Server skapar ett internt uuid som är INT för användaren. Följande lagras på server i tabell users:
```
{
“user_name“: UNAME,
"user_id": UID,
"internal_user_id": IUID,
"perma_nonce": PN,
}
```
### Logga in
Klienten:
- anger lösenord
- genererar nyckel (DK) baserat i lösenordet (P), "Derived Key", enligt standard (ex. PBKDF2).
- Genererar PermaNonce (PN) baserat i P eller DK.
- anger användarnamn (UNAME)
Sedan:
```
{
“user_name“: UNAME,
"perma_nonce": PN,
}
```
Server tillåter nu trafik genom websocket om PN stämmer med vad servern lagrat, annars stäng websocket. Servern vet nu klientens interna användare-ID.
### Skick data
Klienten:
- genererar UUIDv7 för data som ska lagras (DBID).
```
{
“data_block_id“: DBID,
"data": DATA,
}
```
Skickas till servern. Servern vet intern UID för klienten då klienten har genomgått autentifikation.
In i tabellen data_blocks:
```
{
“internal_user_id“: IUID,
“data_block_id“: DBID,
"data": DATA,
}
```
### Hämta/ändra/radera data
Klienten:
- Klienten vet UUIDv7 (DBID) för datan som ska hämtas. Klient skickar bara:
```
{
“data_block_id“: DBID,
}
```
Servern gör direkt select via DBID.
Samma princip för ändra och radera datablock.
## Version 2 med kryptering
Krypterad ... Samma som version 1, men klienten genererar en krypteringsnyckel (EK), den krypteras med DK till KEK (key encrypted key). Klient krypterar data med EK innan det skickas till server. Klient skickar KEK vid något tillfälle för lagring på server. Den behöva för möjliggöra byte av lösenord utan att kryptera om allt. EK baseras inte på lösenordet.
Fortsätta:
[utforma databas](/plan/inquiry)
Arbetar på att hitta en bättre lösning för databaseringsmodellen, skippa idén om ett "index-fil".
[note] Index-filen - klienten har ett index, en sorts karta med ID-nummer, av alla sina data-block. Den skulle krypteras och servern bara lagra den krypterade index-filen, varav servern inte kan veta vilka data-block klienten associeras med. Det är en kvarleva från mina idéer om extrem kryptering och anonymisering av data. Projektlandskapet har ändrats. Jag måste naturligtvis hantera utmaningarna med realtidssynkronisering, och denna relik kastas.
[important] Hur kunde jag missa att realtidssynkronisering är en stor utmaning? Det är klokt av mig att lägga tid på planering innan programmering, vilket sparar mycket tid, undviker förvirring och dilemmat att behöva backa medan jag samtidigt försöker bevara det arbete jag redan lagt ner.
[note] Mina tidigare ansträngningar av självreflektion, som jag har dokumenterat här, lönar sig. Jag ändrar äntligen denna dåliga vana. Tidigare hade jag ett mer impulsivt tillvägagångssätt, där jag hoppade direkt på att skriva koden. Det är roligt och därför lockande att börja programmera med en gång, men det är mycket riskabelt i det långa loppet.
[tip] Om du vill skriva självreflektion för att bli bättre på en enskild sak, begränsa dig inte till att reflektera enbart kring den saken. Tänk fritt och reflektera kring allt som du finner intressant, och pressa din självreflektion så långt du kan i alla riktningar. Du blir bättre på en enskild sak om du förbättrar dig som helhet, och för att förbättra dig som helhet måste du reflektera kring dig själv i alla aspekter av livet, ur alla perspektiv. När tankarna går i olika riktningar är det för att du inte har pressat dig själv i de riktningarna och du har en sorts mental obalans, liksom en bil som drar för mycket åt höger eller vänster. Dina tankar drar åt ett håll för att det är något i ditt mentala system som inte har fått tillräckligt med fokus. Därför måste du fokusera på vad som pressar eller drar hjulen åt det hållet och engagera dig med det för att hitta en tillfredsställande lösning. Därefter kan du fortsätta med annat. När tankarna hoppar till olika saker via associativt tänkande, ska du inte undvika att utforska det, men utforska det tills du är nöjd. Då når du personlig insikt som blir ett fundament i allt annat du gör. Möjligen måste du pressa dig hårt för att bli nöjd, så förvänta dig inga enkla lösningar. Engagera dig ihärdigt och var effektiv, för tiden är begränsad. Se till att forma en insikt som du är nöjd med. Vänta inte på insikt, utan forma den. Skapa ett utkast och förbättra det över tid. Bygg på ditt tidigare engagemang. Du är en aktiv skapare av insikt, inte bara någon som bevittnar något, som i att passivt betrakta något. Men saknar du målfokus och beslutsamhet, så kommer du via denna metod gå dig förlorad i en labyrint av fantasier som inte leder någonstans. Somliga individer har aldrig varit utanför den labyrinten och tycks sky verkligheten och konkreta handlingar. De fantiserar och har fina visioner men kommer aldrig till handling. Egentligen vill de inte göra verklighet av sina visioner, för deras nöje är att fantisera snarare än att möta verkligheten, och de tycks snarare bli förnärmade om det blir tydligt för dem att deras tankar saknar värde eftersom de saknar genomslag i verkligheten (jag har ett existentiellt fokus). De vill egentligen fly verkligheten. Ska du förbättra dig själv, måste du dyka rakt ner i den obekväma verkligheten som får dina drömmar att avdunsta. Men det är också i den konkreta världen, i materian, som du kan skapa något som är mer bestående och påtagligt än fantasier. Det är just där, i den svårformade verkligheten, som du kan härda och forma din identitet. Kom ihåg att ditt fokus är självförbättring, vilket betyder att du ska kunna påvisa konkreta förbättringar.
[caution] Jag bad AI:n [skriva om min text ovan i Nietzsche-stil och i hedonistisk stil](/inquiry/nietzsche).
Klient laddar ner data efter tids-spann helt enkelt. Ska fungera med krypterad version med. Införa ett nytt separat typ-fält för varje rad. Klienten kan skapa sina egna typer, t.ex. typ-matvara, typ-ark, etc. Detta är tabellen för data-block och dess innehåll betraktas som det aktuella tillståndet av användarens data. Skapa en parallell historiktabell för att registrera ändringar i tillståndstabellen, såsom data-block som har lagts till, modifierats eller raderats, för en synkroniseringsfunktion som behöver känna till de senaste ändringarna och verkligen inte vill behöva ladda ner allt innehåll i användarens tillståndstabell igen.
Användargränssnittet/klienten har en tidsbaserad vy, så gränssnittet väljer de senaste X dagarna som sin lokala databas (och kan eventuellt truncera sin lokala kopia). Därmed kan klienten enkelt specificera en tidsperiod. Att återuppbygga den lokala databasen handlar om att välja rader från tillståndstabellen för en viss tidsperiod och sedan bygga en lokal kopia rad för rad. Inte lagra och ladda ner stora JSON block som JSON.parse()'as mellan klient och server.
[note] Men skulle det inte vara bättre att lagra många rader i ett block istället? Klienten behöver ändå inte finjusterad radkontroll, eller? Klienten säger: "Hej, jag behöver uppdatera min lokala kopia, ge mig all data för period x." Det blir problem: jag menar, varje förändring hos klient måste gå in och ändra ett block hos server och skulle kräva att man skickar hela det stora blocket till servern för varje liten uppdatering. Det kan också bli ganska krångligt när realtidssynkronisering är inblandad.
Historiktabellen trunkeras, och om användarens lokala kopia är äldre än det lägsta datumet i historiktabellen, kommer den att återuppbyggas för att bli uppdaterad med historiktabellen.
Denna design gör sig av med den förmodligen slimmade databasdesignen med bara UUIDv7+BLOB för data, vars enkelhet nu blir ett problem med kravet på realtidssynkronisering mellan enheter.
Vad sägs om att ha en flagga is_encrypted i samma rad istället för en separat tabell för den krypterade versionens data?
Skippa Redis just nu. Det är inte prioritet. Vi behöver ändå ett fallback-system som förlitar sig på databasen även om Redis används. Se bara till att det är lätt att implementera Redis senare. Redis skulle förmodligen ge viss prestandaförbättring och vara en snygg metod.
.
##
Ny vecka. Dagens teknikfokus längre ner.
[note] Varför är mitt fokus just nu så mycket på personlig utveckling? Kort svar: utan hälsa blir inte mycket gjort. Jag behöver göra personliga topp-val, och göra blixt-förändringar av dåliga vanor, parallellt med allt annat jag gör. Jag agerar proaktivt, för efter 40 litar jag inte på framtiden såvida jag själv inte tar kommandot. Långt svar: Därför att när du blir 40 ska du redan ha etablerat de bästa rutinerna och förhållningssättet livet. Du ska ha hittat de bästa lösningarna på allt från vardagliga saker till psykologi. Har du inte bestämt dig i basala ting vid det här laget så är det bäst att du skyndar dig. Det är vad jag gör: skyndar mig att ta mitt ansvar att bestämma mig för saker och ting - allt från personligt datorsystem, till skoinlägg, till livsfilosofi etc... Mellan 20-40 ska du experimentera med förhållningssätt och idéer. Efter 40 måste du ha bestämt dig för den bästa lösningen i alla frågor och i alla praktiska ting, så du kan börja förfina det och fördjupa dig i en livsriktning och därigenom uppleva din potential att utforma dig själv i bilden av den du verkligen vill vara om du fick välja (du både får och ska välja). Var inte öppen för allt en hel livstid där du hoppar från en sak till en annan, ständigt osäker och obeslutsam - det vill säga; en som tar dagen som den kommer, snarare än att sätta riktning för dagen, för livet. Välj en riktning, skärma av annat, och fördjupa dig i din valda livsriktning.
Denna gång ska jag utveckla metod för problemlösning (främst avseende it-system, men jag tar det sedan vidare). Kan inte gå enbart på känsla varje gång. All problemlösning kan omfattas av en generell metod. Hitta bästa tillvägagångssätt en gång för alltid.
💭 💡
Sådär... Jag har uppfunnit en ny "utvecklingsmodell" - alltså en framgångs-modell.
Den kallas MEAN - Mål, Effektivisering, Analys, Nytänk.
Jag inspirerades av den Japanska Lean-modellen som skapades av Toyota. Den är en metod för att effektivisera produktion genom att skala bort ovessentligheter.
Det engelska ordet "mean" används i uttrycket "Lean and Mean". I detta sammanhang betyder det första ordet "Lean" att man har skurit bort allt onödigt och fokuserar på det väsentliga, medan det andra ordet "Mean" innebär att man är tuff, bestämd och redo att agera snabbt och kraftfullt. Tillsammans förmedlar uttrycket idén om en slimmad, fokuserad och kraftfull enhet som är redo att nå sina mål utan onödiga hinder eller kostnader.
"Mean" betyder också elak. Min modell är elak och tuff. I steg 1-3 framställer du en lösning. Steg 4 är till för att elakt rasera den lösningen genom outside-the-box tänkande och djupt kritisk analys och ursinnigt ifrågasättande av **både** problemställning och lösning från steg 1-3. Steg 4 ifrågasätter både relevansen av målet i steg 1, och validiteten i lösningen från steg 2 och 3. Avsikten insteg 4 är att på god grund förkasta produkten från steg 1-3. Det är lätt att älska sina egna ambitioner och lösningar, men steg 4 ser till att du ifrågasätter båda och blir tuffare i ditt tänkande. En ny cykel av MEAN startas efter steg 4. I den nya cykeln måste 1-3 nu lösa kritiken från steg 4. När steg 1-3 vinner över steg 4, då är lösningen accepterad. Resultatet är något som är "Lean and Mean".
Första versionen av matkalkyl hade värdeorden "enkel, effektiv och exakt". För att verkligen ta projektet till nästa nivå, ska inte bara produkten vara "Lean and Mean". Mina utvecklings-metoder ska också vara "Lean and Mean". Det antar jag kommer ingjuta dessa värden - den energin - i produkten. Därtill ska jag applicera MEAN-metoden på min personliga utveckling så att jag förbättras i allt jag gör, vilket då ger mig bättre färdighet också i utveckling av denna sida.
Jag AI-genererade [en sammanfattning av MEAN-modellen](/inquiry/mean) som bara är preliminärt formulerad än så länge.
...
Ja, MEAN-modellen tar tuffare tag än min nuvarande metod som bygger på Dale Carnegies metod (som jag skrev om en tidigare dag i november).
Låt AI generera en version för personlig utveckling: [MEAN personlig utv.](/inquiry/mean-personal).
---
Föregående:
1 - Mestadels löst struktur för användarkonton, användardata, autentifikation.
2 - Bestämt typ av primär nyckel i databas för konton, och för användardata (UUIDv7). Det är ett beslut som är mycket svårt att ändra på sedan. Lösningen ska också hålla i 40 år, men kommer antagligen utan problem principiellt hålla i 80 eller mer, samt att databasen inte blir krånglig när den växer.
[caution] Se över hur en stor databas beter sig med UUIDv7. Mina tester visar att 400 000 rader inte är problem. Hur är det med miljoner rader? Hur beter sig indexering etc, hur kommer det optimeras för i framtiden inom databas-teknologi. Vilka inställningar i Databas kan motverka tänkbara problem. Viktigt inte måla in sig i ett hörn.
3 - Konstaterat att full anonymisering och kryptering öppnar för sårbarhet där servern lätt kan fyllas med skräp-data utan möjlighet att identifiera det (när användarens data är krypterad och därför ej synlig på servern). Därför skapar jag två versioner, en fri icke-krypterad, och möjligtvis senare kryptering som tilläggsfunktion mot betalning, eftersom betal-modell är det enda jag ser kan eliminera problemet (PoW är inte aktuellt). Den fria icke-krypterade versionen kommer prioriteras först, men grunden är lagd för att utöka med kryptering. Systemet ska vara en elastisk bas som kan utökas med mer funktioner, varav kryptering blir intressant då mer känslig data kanske lagrad via andra funktioner (säg en Att-göra-lista, eller personlig journal). Utöver det är kryptering en bra funktion för de som inte vill att deras data ska läcka om databasen stjäls, eller för de som helt enkelt vill hålla data privat. Där till, I den icke-krypterade versionen, kommer det inte finnas krav på att ange någon personlig information, precis som föregående version.
4 - Inga komplicerade operarioner, utan bara select, insert, update, delete. Detta eftersom klienten utformar databasens specifika struktur på klientsidan i IndexDB. Servern lagrar bara block med data. Den bryr sog om innehållet.
[caution] Se över att detta fortfarande gäller att inga andra operationer behövs.
Fokus:
1 - Behöver lösning för realtids-synsk mellan enheter. Kommer bli lågintensiv långvariga och lömska problem om det implementeras först när resten av systemet är på plats.
Scenario: anv. har 4 enheter. 1an och 2an direkt uppkopplade. 3an var uppkopplad men har internet-avbrott och kommer tillbaka senare. 4an har inte varit uppkopplad på länge och loggar in.
Mål: Anv. 1an uppdaterar data. Det synkas direkrekt med 2an. 3an redigerar data på sin uppkopplade enhet. 3an kommer tillbaka och får uppdateringen som 1an gjorde. 4an loggar in och får inledningsvis info om alla senaste uppdateringarna.
Hur lång är historiken över förändringar? Den är x lång. Om klient 4an loggat in tidigare än äldsta posten i historiken, måste klienten ladda ner alla aktuella data-block på nytt.
Behov:
I info om att uppdatering skett måste den uppdaterade infon bifogas. Annars måste större data-block laddas ner där uppdateringen ligger.
---
Om allt i ett system är moduler som utvecklas enskilt och har tydligt avgränsat ansvarsområde, då kan varje modul vid skapande genomgå samma utvecklings-bana; problemställning, analys, implementation, etc. Gör sådan utvecklings-bana gemensam för alla komponenter.
##
(använd timestamp för all data, inte time-bucket)
## Version 1
Ej krypterad.
### Skapa konto
Klient:
- väljer lösenord (P)
- genererar nyckel (DK) baserat i lösenordet (P), "Derived Key", enligt standard (ex. PBKDF2).
- Genererar PermaNonce (PN) baserat i P eller DK.
- generera uuidv7 som användar-id. (UID)
- uuid7 är primär identifierare, för enkelhet: användare anger ytterligare identifierar som användarnamn. (UNAME)
Sedan
```
{
“user_name“: UNAME,
"user_id": UID,
"perma_nonce": PN,
}
```
Skickas till server, server lägger in i tabellen "users".
Server skapar ett internt uuid som är INT för användaren. Följande lagras på server i tabell users:
```
{
“user_name“: UNAME,
"user_id": UID,
"internal_user_id": IUID,
"perma_nonce": PN,
}
```
### Logga in
Klienten:
- anger lösenord
- genererar nyckel (DK) baserat i lösenordet (P), "Derived Key", enligt standard (ex. PBKDF2).
- Genererar PermaNonce (PN) baserat i P eller DK.
- anger användarnamn (UNAME)
Sedan:
```
{
“user_name“: UNAME,
"perma_nonce": PN,
}
```
Server tillåter nu trafik genom websocket om PN stämmer med vad servern lagrat, annars stäng websocket. Servern vet nu klientens interna användare-ID.
### Skick data
Klienten:
- genererar UUIDv7 för data som ska lagras (DBID).
```
{
“data_block_id“: DBID,
"data": DATA,
}
```
Skickas till servern. Servern vet intern UID för klienten då klienten har genomgått autentifikation.
In i tabellen data_blocks:
```
{
“internal_user_id“: IUID,
“data_block_id“: DBID,
"data": DATA,
}
```
### Hämta/ändra/radera data
Klienten:
- Klienten vet UUIDv7 (DBID) för datan som ska hämtas. Klient skickar bara:
```
{
“data_block_id“: DBID,
}
```
Servern gör direkt select via DBID.
Samma princip för ändra och radera datablock.
## Version 2 med kryptering
Krypterad ... Samma som version 1, men klienten genererar en krypteringsnyckel (EK), den krypteras med DK till KEK (key encrypted key). Klient krypterar data med EK innan det skickas till server. Klient skickar KEK vid något tillfälle för lagring på server. Den behöva för möjliggöra byte av lösenord utan att kryptera om allt. EK baseras inte på lösenordet.
# Meta Vault, tidigare version
Klienten skickar DBID+EMV till servern. Servern lagrar
(fortsättning följer)
Är tidsbaserst och randomiserat. Klienten genererar själv sina id i alla fall.
---
Nedanstående ej aktuellt.
Använd
Teknologiskt fokus idag: ...
När nu [databas id typ](/decision/dbid) är bestämd kan jag göra klart konceptet [MetaVault](/decision/metavault). Men...
[note] Varför fokuserar jag på integritet (kryptering och anonymisering)? 1) Därför att grundsystemet ska vara flexibelt att kunna utökas med perifiära funktioner som kalender, journal, att-göra-listor och annat tänkbart som kan tänkas lagra mer personlig data. 2) Om databasen blir stulen så är datan ändå inte tillgänglig för angriparen.
Planen var att tänka ut maximal integritet (krypterad ing och anonymisering av data) vilket gick bra. Servern har inget koncept av vad en "användare" är och kan inte se associationer mellan data. Den ser bara krypterad data och långa slumpmässiga id-nummer. Jag behöver som förväntat göra kompromisser. Ett system med hög anonymitet och kryptering kan lätt missbrukas för att sätta det ur spel genom att fylla systemet med skräp-data som servern sedan Inte kan identifiera. En metod är Pow - Prof of Work. Server kräver svar på en uppgift som tar processor-kraft att lösa hos klienten men som är lätt för servern att kontrollera svaret på.
Men nej... Det är att gå för långt i detta fall.
Så... Hur lösa? Jag värderar användar-integritet men det får inte gå ut över funktion.
### Alternativ 1 - ingen kryptering, men som tillägg
2 versioner, en fri version utan kryptering, och en betal-version med kryptering.
- Användares data lagras icke-krypterat. Lätt att spåra skräp-data som yttersta åtgärd ifall de andra automatiska preventiva åtgärderna misslyckats.
Kryptering kan då vara en tilläggsfunktion för den som vill betala för det. Betalning eleminerar alla försök till spam, och om någon ändå försöker betala för det och sedan fylla med spam, då ser servern vilket användar-id som gör så och kan radera datan. Detta skyddar mot att en person registrerar flera konton med kryptering för istället fördela skräp-data över flera konton med målet att fylla systemet.
- En användare har ett UUIDv7.
- All användarens data associeras med det.
Strategi: skapa den icke-krypterade versionen först. Den har prioritet över den krypterade som nu blir en tilläggsfunktion.
#### Möjligtvis PoW som tillägg
Möjligtvis kan kryptering erbjudas fritt som ett tillägg för den som vill aktivera PoW, och för övriga finns föregående alternativ. Betaversionen skulle då vara fri från PoW.
Men frågan är om det vore en lösning som folk vill ha. Isåfall:
- 1 - Fritt, ingen kryptering
- 2 - Frtit, kryptering, PoW
- 3 - Kryptering, betal, ej PoW
### Alternativ 2
Alternativ två är (med tanke på att eliminera attack-vektor som full kryptering öppnar för): Kryptering för alla, med lagrings-gräns på kontot, och betalning för att lätta gränsen. Samt några andra tekniska åtgärder.
**Nej, alternsriv 2 är inte aktuellt.** Tanken är att programmet i sin grundform med all nödvändig funktionalitet ska vara fritt. Jag tror användare uppskattar det mer än hög integritet på servern, och för de som bryr sig om integritet finns alternativ 1.
---
Kommer behöva mer funktioner så som direkt synk mellan enheter. Servern behöver därför associera en användares data under en identitet.
Länkar om annat:
[Sequential UUID Generators | EDB](https://www.enterprisedb.com/blog/sequential-uuid-generators)
[Goodbye to sequential integers, hello UUIDv7! | Buildkite](https://buildkite.com/resources/blog/goodbye-integers-hello-uuids/)
---
Beslut: testa att göra en formaliserad självreflektion varje dag, om tre frågor (nedan).
Det finns en "framgångbok" från 1930 “How to Win Friends and Influence People" (nu public domain) av Dale Carnegie som jag inte läste mer än inledningen till, för många år sedan, men det var nog det bästa rådet för sjävreflektion och något jag alltid tänkt jag ska göra. Varje vecka frågade han sig dessa frågor som jag avser fråga mig varje dag:
### Gårdagsreflektion
#### Vad gjorde jag bra
Gjorde avbrott från datorn för att motionera, trots att jag hade ett system-problem som jag "jag ska bara... Jag ska bara...". Vissa situationer med datorn kan vara så frustrerande att det är svårt att låta bli att försöka lösa dem, varav man tröttar ut sig genom att sitta för länge och därmed får svårare att lösa det, och därtill blir ännu mer frustrerad. Löser jag inte problemet så tänker jag på det hela tiden sedan. Vad är lösningen? Gör rätt. Sluta tänk på det. Gör något annat en stund. Gör något som ger kropp och sinne variation. Viktigt variera.
Analysen av databasen för beslut igår var bra.
#### Vilka misstag gjorde jag
Även om jag lyckades (som nämnt ovan) kom jag inte till rätt handling snabbt nog. Skulle varit snabbare i analys, beslut och handling. Hur snabbt? 2 sekunder, gärna 1. Igår tog det nog 20 minuter.
#### Vad kan jag göra bättre
Vad har jag för attityd när jag sätter mig vid datorn? Lätt att man driver från en kreativ sak till en annan och bara gör det som är skoj, och skjuter tråkigare moment av ett projekt framför sig.
Vad är bättre förhållningssätt?
---
För 20 år sedan läste jag igenom endel "framgångsböcker". De påstår vanligtvis att metod X är hemligheten till allt osv. Boken "7 habits of highly successful people" etc. Det är sådant man läser när man är yngre och tror att en magisk tanke-formel kommer generera ändlös framgång. Vad är hemligheten? Hemligheten är att vara engagerad. Hur blir man engagerad? Vad är den hemliga metoden för det? Nej.... Tänk inte så. Tänk istället: Engagemang är som dina ben, de rör sig när du vill. Om du inte vill engagera dig så är du inte intresserad. Du är fel ute och kommer inte lyckas på så sätt att du känner att du utmanar och uttrycker din potential. Om du känner en aktivitet är oengagerande så värderar du inte resultatet. För att hitta engagemang, fråga dig vilket resultat du vill ha. Med vilja till resultat kommer du vara engagerad i att lösa de motgångar som står i vägen för framgångar. Just och precis i spänningsläget mellan motgång och framgång blossar livsgnista upp i en eld av engagemang. Då säger man att något är "spännande". I gränslandet mellan motgång och framgång upplever du din vilja. Vilja = att vara levande. Att "inte bry sig om livet" är att vara viljelös. Det kanske signalerar en kulturell attityd om att vara tuff etc, men i mötet med verkligheten är det en svag hållning då attityden lämnar dig oförberedd och slutligen missgynnad, dels av din egen försummelse och dels av andra krafter. Somliga vill inte något särskilt och tycks acceptera dagen som den är och väntar ständigt på att "något roligt" ska hända. Inte sällan uppstår saker som vardags-depression och andra destruktiva tankegångar, just för att de inte har något att engagera sig med. Hur hitta sitt engagemang? Fråga dig vilka aktiviteter som gör dig till en bättre, starkare och smartare människa. Livsglädjen ligger inte i aktiviteten resultat utan i engagemanget i stundens nu. När du är genuint engagerad, på så vis att du känner livsglädje och spänning i det du gör, då kommer framgång av sig själv, och den framgången är personlig och sekundär den personliga utvecklingen du genomgår. Titta inte på andras framgång, fråga dig istället: hur har de förädlas, eller inte, som människa, genom att uppnå sin framgång.
Engagemang kanske kommer lätt för somliga tidigt i livet. Det har inte mycket värde om det senare avtar (vanligt på äldre dagar). Poängen är att hitta ett engagemang som inte avtar oavsett vad. För det behöver du en friktion som inte avtar. Livet i sig själv och att bibehålla vitalitet och att göra bra val i svåra omständigheter är all den friktion du behöver och tar aldrig slut så länge du är på jorden. Intressant är att om du inte själv väljer friktion, så kommer friktion att välja dig, förr eller senare.
##
Detta är ett beslut som ska hålla i minst 40 år, och är svårt att ändra om jag väljer fel. Därför har jag gjort tester och sammanställt statistik och analys av UUID. UUIDv4 är vinnaren. Sekventiella heltal var dessutom inte alltid effektiva. Min föregående idé visade sig sämst när jag testade.
[Här är jämförelsen](/inquiry/uuid-test) och nedan är en sammanfattning:
> Testerna av MariaDB visar att UUIDv7 generellt presterar bättre än UUIDv4 och sekventiella heltal. Vid både insättning och uppdatering av poster visade UUIDv7 lägre läs- och skrivoperationer samt kortare exekveringstid. Sekventiella heltal var snabbast vid insättningar men krävde mer resurser för uppdateringar. Sammantaget ger UUIDv7 en balans av snabbhet och effektiv datahantering, medan sekventiella heltal ger hög insättningsprestanda men med högre resursanvändning vid andra operationer. UUIDv4 hade genomgående den långsammaste prestandan. (ChatGPT sammanfattning)
---
UUID är inte så dåligt som primär nyckel som folk på internet verkar tycka. MariaDB är optimerat för det till viss grad. Allt i databaser lagras i rader i tabeller. Databasen omplacera tabell-rader i B-träd för att underlätta sökning. Databasen delar upp tabell-rader intervaller som 0-10, 10-20 etc. Då kan den snabbare hoppa till segment 10-20 om den söker efter 15 och skippa söka föregående. UUID har stor slumpmässighet och gör trädet fragmenterad, men databasen har vissa optimeringar för det. UUIDv7, i kontrast till UUIDv4, undviker vissa problem med sin sekventiella tidsbundna natur.
UUIDv4/7 finns i ny version av MariaDB. Installera MariaDB > 11.7 för UUIDv4(). Måste installera manuellt. Den är för ny. Inte än i paketsystemet.
[UUIDv4 - MariaDB Knowledge Base](https://mariadb.com/kb/en/uuidv4/)
Vill ha den för att köra prestanda test med UUIDv4, då jag funderar på att välja den. Ska installera den manuellt.
Nuvarande test med UUIDv1 är i samma klass som att använda sekventiell nummer, vilket förvånar mig då endel avråder från UUID som primär nyckel.
Håller på med predtandardtest med UUID och andra typer.
### Test på server
[note] Notera att jag enbart kommer använda seelct, insert, update, delete. Datan är krypterad, därför ingen användning för annat.
Inte det mest sofistikerade test, men visar ändå på vad som sker. Sätt in 100 rader, 100 omgångar, ta genomsnitts värden på det. Databas hade redan > 350 000 rader vid testet.
| Test Type | Duration | Cache Hit Ratio | Data Reads | Data Writes | Data Read (Bytes) | Data Written (Bytes) | Final Rows |
|------------------------|----------------------|---------------------|------------|-------------|--------------------|-----------------------|------------|
| repeat_insert (100,100)| N/A | N/A | N/A | N/A | N/A | N/A | N/A |
| test_bigint_smallint | 206,869 µs (avg) | 86.00% | 31,024 | 15,920 | 508,297,216 | 188,497,920 | 378,125 |
| test_bigint_int | 211,382 µs (avg) | 85.79% | 30,094 | 18,547 | 493,060,096 | 268,926,976 | 378,125 |
| test_sequential_int | 189,051 µs (avg) | 94.08% | 14,679 | 15,783 | 240,500,736 | 177,815,552 | 378,125 |
| test_uuid | 189,515 µs (avg) | 92.08% | 23,308 | 11,771 | 381,878,272 | 44,761,088 | 378,125 |
Av ovanstående är det iallafall fastställt att BIGINT varianterna inte är bra alls.
Samma mönster visas vid återkommande tester.
[caution] Förresten, är mitt test inte tillräcklig simulering av real-world-case. Det visar på bulk prestanda.
### Jämförelse mellan `test_uuid` och `test_sequential_int`
| Parameter | test_sequential_int | test_uuid | Skillnad |
|------------------------|---------------------|-------------------|---------------------------------------|
| **Duration (µs)** | 189,051 | 189,515 | `test_uuid` är marginellt långsammare |
| **Cache Hit Ratio** | 94.08% | 92.08% | `test_sequential_int` har bättre cacheträffar |
| **Data Reads** | 14,679 | 23,308 | `test_uuid` har betydligt fler läsningar |
| **Data Writes** | 15,783 | 11,771 | `test_uuid` har färre skrivningar |
| **Data Read (Bytes)** | 240,500,736 | 381,878,272 | `test_uuid` använder mer läsdata |
| **Data Written (Bytes)** | 177,815,552 | 44,761,088 | `test_uuid` använder mycket mindre skrivdata |
Aspekter: Innodb_buffer_pool_reads, Innodb_buffer_pool_read_requests, Innodb_data_reads, Innodb_data_writes, Innodb_data_read, Innodb_data_written.
---
Psykologi: Det är populärt att sträva att vara mer medveten och närvarande (därmed "mindfulness"-kurser etc). Om du verkligen faktiskt blir mer medveten kommer du antagligen inte gilla det, för du inser ansvaret du annars så behagligt flyr genom att just vara icke-medveten. Jag syftar inte på "medveten" så som i politik, där ägande av "rätt" åsikt felaktigt likställs med att vara medveten. Jag syftar exakt och enbart på att vara medveten om din egen vardag och de ansvar du har gentemot dig själv. Ignorans är ett opium.
Hur blir man mer medveten? En enkel väg är att skapa en morgonrutin där du först motionerar på något vis för att syresätta kropp och hjärna. Gör meditation 5-10 minuter minst där du fokuserar enbart på en upplevelse (ex upplevelse av andning i magen eller enbart observerar alla tankar som uppstår utan att engagera dem), detta för att minska tendens till impulsivitet; önskvärt eftersom impulsivitet föranleder dåliga och verklighetsfrånvända beteenden genom en slarvig och impulsiv värdering av det du har framför dig. Impulsiva beteenden är verklighetsfrånvända på så sätt de ignorerar konsekvenser. Verklighetens lagar straffar dig på lång sikt för dåliga beteenden (ex. livsstilsfaktorer påverkar hälsa). Du vänder blicken bort från den verklighet som gäller. Utöver motion och enkel meditation: Tänk också igenom dagen; vad du har framför dig. På detta sätt blir du mer medveten.
##
border-bottom: 2px solid #FFFBCC;
När klienten skapar ett konto sker det i två steg
### Steg 0
Klienten, besöker matkalkyl.se via webbläsare, erhåller JavaScript kod (själva matkalkyl-programmet) som körs i klientens webbläsare.
### Steg 1 - nytt konto
I detta steg har klienten ingen kontakt med webservern. Allt i steg 1 körs på klientens enhet.
Klienten:
- väljer lösenord (P) (kan välja användarnamn med, men är inte basalt)
- genererar en krypteringsnyckel enligt standard (EK).
- genererar nonce (N) (unik sekvens med karaktärer, används senare för autentifikation).
- ett grupperings-id (GID) mellan 0 och 18446744073709551615.
Sätt ihop allt till ett paket (MV - Meta Vault):
```
{
"encryption_key": "EK",
"nonce": "N",
"grouping_id": "GID"
}
```
Generera nyckel (DK) baserat i lösenordet (P), "Derived Key", enligt standard (ex. PBKDF2).
Kryptera MV med DK, och vi får EMV (Encrypted Meta Vault).
Klienten genererar ett annat id som är användar-id (UID). Det är ett UUIDv4, ett nummer mellan 0 och 340,282,366,920,938,463,463,374,607,431,768,211,455.
Det är 340.3 quintillioner. Det beräknas finnas 7.5 quintillioner sandkorn på jorden. Vi är i praktiken garanterade att få ett unikt användares. Det är därför klienten själv kan generera anvöndar-id utan serverns vetskap. Att göra det själv är
(fortsättning följer)
---
Testar hur det egentligen står till med olika modeller. Förvånad. Jag har antagligen rätt att databaser övertid förbättrar för UUID och det är ett bra framtidsval:
[Enkel prestanda test olika typer databas](/plan/dbtest)
Är inte enligt med följande mer sofistikerade test, [UUID Benchmark War | Ardent Performance Computing](https://ardentperf.com/2024/02/03/uuid-benchmark-war/)
Antingen har jag för primitivt test och andra förutsättningar, eller så är det som chatgpt säger, att MariaDB är optimerat bättre.
Blir att göra bättre test på servern.
Fortsätter utarbeta [meta-valv](/decision/metavault). Går bra men...
Känner att jag för stunden har mediokert fokus. Inte önskvärt. Vad är lösningen? Behöver morgonrutin för att tänka igenom dagen på förhand? Behöver definitivt variera med motion. Detta är inte skoj. Måste ändra på mina (o)vanor. Måste faktiskt åstadkomma skillnad i vardagen. Tänk att det kan kännas motigt att göra rätt. Lösningen är såklart: Gör rätt. Om man inte kan göra rätt då?! Ja så är det. Somliga lyckas inte, och så är det bara. Man får fråga sig själv om man nöjer sig med det. Är man inte nöjd så fortsätter man att kämpa. Kampen ger energi och livsglädje. Via kamp är man engagerad. Engagemang är rörelse. Rörelse är liv. Det som stannar upp stagnerar. Stillastående vatten är inte bra. Gäller allt från kropp till själ. Sök ett problem att brottas med. Sök friktion. Sök något som är svårt. Sök något som frustrerar. Välkomna det som andra flyr. Vakna och förvänta dig att det kommer bli en svår dag, och om dagen är för lätt, hitta något som gör den svårare (det finns antagligen alltid en till ovana som du kan brottas med om du tittar noga).
Psykologi: Beslutsångest, igen gällande databas struktur. Var uppmärksam på språket för att beskriva upplevelser. Byt ut "beslutsångest" mot "starkt fokus". Du formas via hur du tänker kring upplevelser. Då säger någon att risk är att man förtränger. Att man snarare ska bekänna sin känsla och vältra sig i det. Nej. Kärnan är att byta ut en tanke mot en annan som svarar bättre mot verkligheten. Om istället du byter ut "beslutsångest" mot "starkt fokus", och du sedan ändå misslyckas, då har du inte gjort rätt. Det räcker inte att bara välja en behaglig affirmation som "jag klarar detta". Du måste också förena det med handling. Välj rätt tanake som uppmuntrar ett förhållningssätt som ger bättre resultat när du agerar efter det. Resultatet är det i slutändan som avgör värde av ditt förhållningssätt. Orden är nycklar till förhållningssätt, och förhållningssätt är vägarna som dörrarna öppnar till. Tänk på att sättet du uppnår ett resultat på, själva utförandet, är lika viktigt, därför att du är vad du gör och hur du gör det, inte vad du uppnår. Tendens i människan är att klä sig i result och andra attribut för att dölja för sig själv den man är (dvs. ens dag-för-dag förhållningssätt).
Därför... Jag är inte nöjd enbart med resultatet utan jag vill förbättras som person via mit engagemang, annars är jag inte nödj. Det betydder: bli starkare, snabbare, smartare i alla avseenden. Vad är ett resultat värt om du är den samma som innan du började? Det viktigaste resultatet är dig själv.
##
Sedär! Mitt dokumentstionssystem (denna sajt) som integrerar direkt med min telefon och dator, via Syncthing och Obsidian och NeoVim, fungerar utmärkt. Jag tänkte jag kanske kastat bort tid på detta, men nej! Jag behöver verkligen ett dynamiskt dokument-system
Fråga .... UUID eller integer
Bakom varje stort projekt finns en struktur
UUID exempel `0acca9b1-0909-4de1-9dc1-4874306f394f`, integer exempel `1029`.
Säg
Jag besegrar effektivt min mentala dimma från igår. Databas-design känns överväldigande. Varför? Databasen är ju relativt lite arbete, men inom några få
>Sannolikheten
**Nu har jag kommit till beslut:**
Ledorden som ska samsas är "anonymitet", "kryptering", och "effektivitet."
Beslut [databas data typ](/decision/blob)
Beslut [databas id-typ](/decision/dbid)
Beslut [autentifikation](/decision/permanonce)
På gång [meta-valv](/decision/metavault)
---
Bestäm databas-egenskaper. Databas utformas med [kryptering](/@backend-encryption) och anonymisering. Kompromisser behöver göras.
Tidiga beslut är viktiga
Vad är hemligheten till skalbar design? Som vanligt: modulärt, lösa kopplingar mellan komponenter (dvs ej beroende av varandra så ex.
Istället för att förutse alla framtida behov, gör det istället lätt att utöka. Check ✅ på det. Skapa inte strukturer för funktioner du ej behöver. Men (!) problemet
Såklart kan jag göra bra moduler. Problemet är på högre nivå, när moduler ska samverka. Där uppstår
Förslaget är gränssnittsdriven design, och abstraktion. Problemet är att abstraktion lätt tas
Fördel, uuid
Fokusera domänspecifikt: vad är det konkreta användarområdet. Gör sedan ett bra gränssnitt för det, och bara det. Lösningen tycks vara att andra komponenter kan lita
Undvik lägg in extra funktioner i gränssnittet som
> Genom att hålla varje modul fokuserad på sin kärnfunktion och undvika att ge efter
Att läsa [UUID vs. Sequential ID as Primary Key | Baeldung](https://www.baeldung.com/uuid-vs-sequential-id-as-primary-key)
Benchmark [UUID Benchmark War | Ardent Performance Computing](https://ardentperf.com/2024/02/03/uuid-benchmark-war/)
Gid + rolling time window. Separate table. Thus no stamp on each block.
-
```
CREATE TABLE users (
user_id Unsigned int PRIMARY KEY, -- Unique identifier for each user
username VARCHAR(255) NOT NULL UNIQUE, -- Unique username
encrypted_meta TEXT NOT NULL -- Encrypted meta field, contains user's group ID, index UUID, and encryption key
);
```
```
CREATE TABLE data_entries (
uuid unsigned int PRIMARY KEY, -- Unique identifier for each data entry
group_id unsigned int NOT NULL, -- Group ID unique to each user, but not linked with users table
encrypted_data TEXT NOT NULL, -- Encrypted data content
nonce_hash CHAR(64) NOT NULL -- Hash of the nonce for update and retrieval verification
);
```
```
CREATE TABLE group_time_buckets (
group_id unsigned int PRIMARY KEY, -- Primary key for each group, unique to each user
-- Not char 64
rolling_window_hash CHAR(64) NOT NULL -- Hash representing the current rolling time window for the group’s data
);
```
Daglig reflektion:
Jag är inte intresserad om jag inte kan lära mig något nytt via det jag gör. Att ständigt fördjupa min färdighet. Därför skriver jag en självreflektion nästan varje dag. En medveten lärprocess via självreflektion. En journal systematiserar självreflektionen.
[tip] En människa utan strukturerad reflektion tror lätt på sin egen storhet. Strukturerad reflektion visar dig det du vanligtvis inte vill eller kan se; både styrkor och svagheter. Det du inte vill se inom dig själv håller dig tillbaka från framgång. Dyrka inte det som är dolt inom dig genom att låta det vara dolt, för det har inte ditt bästa i sitt intresse. Låt ljus och medvetande in. Det är så du bemästrar dig själv. Hur kan du bemästra dig själv utan insyn i vem du är? Du är vad du gör. Börja skriv vad du gör, och reflektera kring det.
Lättaste sättet att följa projektet är att läsa *[senaste nyhetsbrevet](/nl)* som jag publicerar sista dagen varje månad. Jag tror den metoden kommer funka!
2. Klienten erhåller bevis från Auth-servern och skickar till MK-servern, som i sin tur frågar Auth-servern
Egentligen behövs inte Auth-servern.
Men nej. Märk väl att
2. Steg 2 ej angivet.
Lättaste sättet att följa projektet är att läsa *[senaste nyhetsbrevet](/nl)* som jag publicerar sista dagen varje månad. Jag tror den metoden
## Detaliijer
Som nämnt ovan, det lättaste sättet att följa projektet är att läsa *[senaste nyhetsbrevet](/nl)*, men här nedan kommer lite annan info som jag har för egen skull. Mycket av detta uppdateras automatiskt.
-
background-color:#ffff0022;
}
// Split both strings by space to get arrays of words
const wordsA = a.split(' ');
const wordsB = b.split(' ');
// Map through words in a and wrap if not found in b
const highlighted = wordsA.map(word => {
// Check if the word from 'a' exists in 'b'
return wordsB.includes(word) ? word : `${word}`;
});
// Join the result back into a string with spaces
return highlighted.join(' ');
}
// Example usage:
let previousMessage = ''; // Variable to store the previous message
const result = highlightDifferences(stringA, stringB);
console.log(result); // Output: This is an example string
if (!Array.isArray(category)) {
category = category ? [category] : [];
}
let categoryText = '';
if (category.length > 0) {
categoryText = category.map(cat => {
// Split each category by the first \r if present
const [catText, tooltipText] = cat.split('\r');
return
}).join(' ');
}
// Compare the current message with the previous message and highlight differences
const highlightedMessage = highlightDifferences(message, previousMessage);
// Add the message content to the message div
previousMessage = message;
padding:0 4px;
}
if (event.data === 'pong') {
} else {
// Include the "from" field between the timestamp and the message if available
const color = generateColorFromText(from+"sxccx2vxdsssxx" || '', 50, 30);
const bg = generateColorFromText(from || '', 30, 90);
const border = generateColorFromText(from || '', 70, 70);
const fromText = from ? `${from} ` : '';
const color2 = generateColorFromText(category || '', 50, 30);
const bg2 = generateColorFromText(category || '', 30, 90);
const border2 = generateColorFromText(category|| '', 70, 70);
const categoryText = from ? `${category} ` : '';
name // Store the name
// Function to generate a consistent HSL color based on a string (innerHTML)
function generateColorFromText(text, saturation = 70, lightness = 50) {
// Create a hash based on the text
let hash = 0;
for (let i = 0; i < text.length; i++) {
hash = text.charCodeAt(i) + ((hash << 5) - hash);
}
// Convert the hash to a hue value (0 - 360 degrees on the color wheel)
const hue = Math.abs(hash % 360); // Ensures the hue is always positive and within [0, 360]
// Return the HSL color as a CSS-compatible string
return `hsl(${hue}, ${saturation}%, ${lightness}%)`;
Detta loggsystem
Det som loggas är enbart system-filer, dvs. serverns konfiguration och programkod. Uppdatering av dokumentation hamnar inte här. Detta
def