Easy-to-manage touch screens
Free, open-source touch screens. Guided USB setup, a drag-and-drop editor and local control. Made for Home Assistant.
翻訳待ち
No updates detected yet. GitHub releases will appear here.
Loading the full README. The saved excerpt is shown below.
Dansk lejeboligportal. Aggregerer ledige lejeboliger fra flere kilder, lader brugeren søge gratis, og tager betaling for at kontakte udlejeren. Se BRIEF.md for produktet og CLAUDE.md for reglerne i mappen. Databasen ligger på Supabase. Railway beholdes udelukkende til scraper-workeren. Supavisor er indbygget, så der skal ikke køre en pooler-service nogen steder. Workeren går uden om den: den er én lang proces med sin egen pool, den har intet at multiplekse, og session/direct lader den beholde prepared statements. To connection strings, og de er ikke ombytteligeRead the full README ↗
Dansk lejeboligportal. Aggregerer ledige lejeboliger fra flere kilder, lader brugeren søge gratis, og tager betaling for at kontakte udlejeren.
Se BRIEF.md for produktet og CLAUDE.md for reglerne i mappen.
Databasen ligger på Supabase. Railway beholdes udelukkende til scraper-workeren.
Vercel Supabase
┌──────────┐ ┌─────────────────────────┐
│ Next.js │──── :6543 ──▶│ Supavisor │
│ frontend │ transaction │ transaction mode │
└──────────┘ │ │ │
│ ▼ │
Railway │ ┌───────────┐ │
┌──────────┐ │ │ Postgres │ │
│ worker │──── :5432 ──▶│ │ │ │
│ (scraper)│ session/direct └───────────┘ │
└──────────┘ └─────────────────────────┘
Supavisor er indbygget, så der skal ikke køre en pooler-service nogen steder. Workeren går uden om den: den er én lang proces med sin egen pool, den har intet at multiplekse, og session/direct lader den beholde prepared statements.
| Variabel | Port | Peger på | Bruges af |
|---|---|---|---|
DATABASE_URL | 6543 | Supavisor, transaction mode | Vercel-frontenden |
DATABASE_URL_DIRECT | 5432 | Session pooler eller direct | Worker og drizzle-kit |
Migrationer skal køre på DATABASE_URL_DIRECT. DDL og advisory locks
kræver en session, og transaction mode giver en tilfældig
server-forbindelse per transaktion. drizzle.config.ts peger derfor
bevidst på 5432.
Direct connection (db.<ref>.supabase.co:5432) er IPv6-only på nye
Supabase-projekter. Virker din maskine eller Railway ikke på IPv6, så tag
session pooleren på port 5432 i stedet — den er IPv4 og kan lige så
godt holde en session.
postgres.js bruger prepared statements som standard. Bag Supavisor i
transaction mode lander næste transaktion måske på en anden
server-forbindelse, og så fejler den med "prepared statement does not
exist" — typisk først under belastning, hvilket gør den ubehagelig at
finde.
db/client.ts sætter derfor prepare: false, når koden kører på Vercel,
og lader dem være slået til i workeren.
Supabase eksponerer public-skemaet gennem PostgREST. En tabel uden RLS
kan læses af enhver med den offentlige publishable-nøgle — også
listings.contact_email, som er præcis det, betalingsmuren sælger.
Migration 0001_enable_rls.sql slår RLS til på samtlige tabeller og
opretter med vilje ingen politikker: Bofinda taler med databasen over
en almindelig Postgres-forbindelse som ejer-rollen, og den går uden om
RLS. anon og authenticated får dermed adgang til ingenting.
Ny tabel skal have enable row level security i samme migration.
Tallene afhænger af Supabase-planen. Slå dem op under Project Settings → Database, og fordel dem sådan:
| Forbruger | Går på | Forbindelser |
|---|---|---|
| Vercel-lambdaer | Supavisor :6543 | 5 hver, mange klienter |
| Worker på Railway | :5432 | 5 |
drizzle-kit, psql, ad hoc | :5432 | 5 |
Frontenden tæller mod Supavisors klientgrænse, ikke mod Postgres'
max_connections. Rykker tallene sig, er pool size i Supabase-dashboardet
knappen der skal drejes på — ikke max i Drizzle-klienten.
npm install
cp .env.example .env # udfyld begge DATABASE_URL'er
npm run db:generate # laver migration af db/schema.ts
npm run db:push # kører den — mod DATABASE_URL_DIRECT
| Kommando | Gør |
|---|---|
npm run dev | Next.js lokalt |
npm run typecheck | tsc --noEmit |
npm run db:generate | Migration ud fra skemaet |
npm run db:push | Kører migrationer (direkte forbindelse) |
npm run import | Kører importen én gang |
npm run db:backup | Dumper hele databasen til backup/ |
npm run db:backup:proev | Genskaber nyeste dump i en lokal base og tæller efter |
npm run tjek:noegler | Prøver kodeord og nøgler i .env — printer ingen værdier |
Lokalt sættes VERCEL ikke, så klienten vælger worker-profilen og går på
DATABASE_URL_DIRECT. Det er det rigtige til udvikling.
Free-planen hos Supabase tager ingen automatiske backups, og der er kun én database — udvikling og produktion er den samme. Går den tabt, er boligerne, alarmtilmeldingerne og udlejerkontiene væk.
npm run db:backup # → backup/bofinda-<tidsstempel>.sql
npm run db:backup:proev # genskaber den nyeste og tæller efter
backup/ er i .gitignore. Filen indeholder adgangskode-hashes fra
auth.users. Den må ikke committes eller sendes nogen steder hen.
Der er ingen pg_dump på maskinen — og ingen brew til at hente den — så
dumpet skrives med databasens eget COPY-format gennem postgres.js. Det
svarer til pg_dump --data-only:
| med | alle rækker i public, og auth.users (udlejerkontiene) |
| ikke med | tabeldefinitioner — dem laver db/migrations, som ligger i git |
| ikke med | filerne i storage-bucket'en. Se nedenfor. |
Hele dumpet tages i én transaktion (repeatable read), så alle tabeller
ses i samme øjeblik. Uden det ville listings blive læst kl. 12.00.01 og
listing_images kl. 12.00.31, og et billede oprettet derimellem ville
pege på en bolig, filen ikke har.
Filen indeholder ingen truncate og ingen delete. Køres den mod
en base med data i, fejler den på en nøglekonflikt. Det er med vilje: en
backupfil, man kommer til at køre, må ikke kunne slette noget.
Til sidst i filen står et manifest med rækketal og en SHA-256 pr. tabel.
Mangler halen -- FÆRDIG, blev dumpet afbrudt. Passer en kontrolsum ikke,
har filen taget skade siden.
Ind i en tom base — et nyt Supabase-projekt eller en lokal Postgres:
This is the beginning of the README. Read the rest at the original. Read the full README ↗