Lalabase
Tickets, Doku, Zeiterfassung und Kundengespräche an einem Ort, durchsuchbar per KI. Für Softwarefirmen mit Kundenprojekten. Open Source: auf deinem eigenen Server oder in unserer Cloud in Deutschland.
翻译准备中
尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证App for organizing ZEV
翻译准备中
取自仓库 README
正在加载完整 README。 以下为已保存的摘录。
Web aplikacija za svakodnevno i godišnje upravljanje jednom Zajednicom etažnih vlasnika (ZEV) u Republici Srpskoj (BiH): imovina i vlasništvo, skupština i sigurno elektronsko odobravanje, fakturisanje i uplate, troškovi i dobavljači, godišnji planovi, održavanje, dokumenti, izvještaji i revizorski trag. Interfejs je na srpskom (latinica); i18n sloj omogućava dodavanje jezika bez izmjene logike (src/lib/i18n).查看完整 README ↗
Web aplikacija za svakodnevno i godišnje upravljanje jednom Zajednicom etažnih vlasnika (ZEV) u Republici Srpskoj (BiH): imovina i vlasništvo, skupština i sigurno elektronsko odobravanje, fakturisanje i uplate, troškovi i dobavljači, godišnji planovi, održavanje, dokumenti, izvještaji i revizorski trag.
Interfejs je na srpskom (latinica); i18n sloj omogućava dodavanje jezika bez izmjene logike
(src/lib/i18n).
Pravne i finansijske pretpostavke, mapiranje na Zakon o održavanju zgrada RS (101/11) i stavke koje mora potvrditi pravnik/računovođa:
LEGAL_AND_FINANCIAL_ASSUMPTIONS.md. Arhitektura:ARCHITECTURE.md. Matrica prava:PERMISSION_MATRIX.md.
Next.js 15 (App Router) · TypeScript · PostgreSQL 16 · Prisma 7 (WASM, bez Rust binarki) · Tailwind CSS · Zod · jose + bcryptjs (sesije u bazi) · pdfkit + DejaVu (sr-Latn PDF) · qrcode · Vitest (62 testa) · Playwright smoke e2e.
Preduslov: Docker Desktop (Windows/Mac) ili Docker Engine + Compose plugin (Linux). PostgreSQL i Node.js nisu potrebni na računaru — sve ide u kontejnere.
docker compose up -d --build
Prvo pokretanje traje nekoliko minuta (build). Zatim otvorite http://localhost:3000 i prijavite se demo nalogom (tabela ispod). Šta se dešava automatski pri startu: kontejner sačeka bazu, primijeni migracije, ubaci demo podatke (samo ako je baza prazna — seed je idempotentan) i pokrene server.
Korisne komande:
docker compose logs -f app # logovi aplikacije (i ispis seed-a sa demo nalozima)
docker compose down # zaustavi (podaci ostaju u volume-ima)
docker compose down -v # zaustavi i OBRIŠI podatke (baza + generisani PDF-ovi)
Podešavanja su u docker-compose.yml: za produkciju obavezno promijenite
SESSION_SECRET i POSTGRES_PASSWORD (na oba mjesta u fajlu), a SEED_ON_START
postavite na "0" kada demo podaci više nisu potrebni. Podaci žive u imenovanim
volume-ima zev-pgdata (baza) i zev-storage (generisani dokumenti).
Napomena: Docker konfiguracija je pažljivo pripremljena i validirana (
docker compose config, sintaksa, idempotentan seed), ali sam build slike nije mogao biti izvršen u razvojnom sandbox okruženju jer su registry-ji slika tamo blokirani. Ako build kod vas zapne, javite tačnu poruku greške.
Preduslovi: Node.js ≥ 20, PostgreSQL ≥ 14.
# 1. baza
createuser zev --pwprompt # lozinka npr. zev_dev_password
createdb zev -O zev
createdb zev_test -O zev # za testove
# (ili u psql)
# CREATE USER zev WITH PASSWORD 'zev_dev_password' CREATEDB;
# CREATE DATABASE zev OWNER zev; CREATE DATABASE zev_test OWNER zev;
# 2. aplikacija
npm install
cp .env.example .env # uredite DATABASE_URL i SESSION_SECRET
# 3. šema + demo podaci
npm run db:migrate # primjenjuje prisma/migrations
npm run db:seed # realistični demo podaci
# 4. pokretanje
npm run dev # http://localhost:3000
# ili produkcijski:
npm run build && npm start
scripts/migrate.mjs pokreće službeni Prisma schema engine u WASM izdanju (paket sa npm-a),
pa migracije rade i u okruženjima bez pristupa binaries.prisma.sh. Direktoriji i tabela
_prisma_migrations su standardni, pa na mašini s normalnim pristupom mreži možete
koristiti i npx prisma migrate dev.
| Komanda | Radnja |
|---|---|
npm run db:migrate | primijeni neprimijenjene migracije (kao migrate deploy) |
npm run db:migrate:new <naziv> | generiši novu migraciju iz izmjena šeme |
npm run db:reset | obriši šemu + primijeni sve + (ručno) npm run db:seed |
Aplikacija je konfigurabilno prenosiva preko više okruženja — Docker self-host
(podrazumijevano, iznad), Vercel, ili bilo koji drugi Node ≥ 22 hosting — bez izmjene koda,
samo promjenom konfiguracije. Puna analiza i odluke: Plans/deployment-portability-plan.md.
Migracija prije deploy-a aplikacije, ne poslije — nova verzija koda očekuje novu šemu, pa migracije moraju biti unazad kompatibilne sa prethodnom verzijom koda tokom prozora između ova dva koraka:
# 1. lokalno ili u CI, protiv produkcione baze (connection string obavezno između navodnika)
MIGRATE_DATABASE_URL="postgresql://…" node scripts/migrate.mjs apply
# 2. deploy aplikacije (npr. `vercel deploy --prod`, ili push na repo povezan sa Vercel-om)
Ne migrirati unutar platforminog build koraka: scripts/migrate.mjs zahtijeva
@prisma/schema-engine-wasm (devDependency, dostupan pri build-u, ali ne u production
install-u), a build se dešava i za preview/branch deployment-e — automatska migracija u
build koraku bi značila da PR preview može migrirati produkcionu bazu.
Pun spisak sa objašnjenjima je u .env.example; sljedeće su posebno bitne van Dockera (gdje
docker-compose.yml već postavlja razumne vrijednosti umjesto vas):
| Varijabla | Obavezno? | Napomena |
|---|---|---|
DATABASE_URL | da | Pooled connection string (npr. preko platforminog PgBouncer-a/Neon/Supabase poolera) |
MIGRATE_DATABASE_URL | ne | Direktan (unpooled) connection string za migraciju produkcije — pooler u transaction modu ne podržava DDL/advisory lock-ove koje migracioni engine koristi. Od 2.54.1: prazna vrijednost se odbija; bez nje apply radi samo uz --local (to rade npm run db:migrate i db:setup) protiv DATABASE_URL; reset radi samo na lokalnoj bazi; skripta prije rada ispisuje cilj (host i bazu, bez lozinke). |
DB_POOL_MAX | ne | Ograničava veličinu pg connection pool-a po instanci (podrazumijevano 10). Bitno na serverless-u, gdje više istovremenih instanci × neograničenih 10 konekcija svaka može iscrpiti limit baze — ako DATABASE_URL već ide preko poolera (gornji red), ovo obično nije potrebno. |
SESSION_SECRET | da | openssl rand -hex 32 |
APP_URL | da, u produkciji | Javan URL aplikacije (linkovi, QR kodovi, e-mailovi) — startup sada puca sa jasnom greškom ako nedostaje, umjesto da tiho generiše neispravne linkove |
EMAIL_PROVIDER | ne (podrazumijevano mock) | mailjet za pravi e-mail — vidi §„Šta je mock" niže |
MAILJET_API_KEY / MAILJET_API_SECRET / MAILJET_FROM_EMAIL | samo uz EMAIL_PROVIDER=mailjet | vidi §„Šta je mock" niže |
MAILJET_FROM_NAME | ne | rezervno ime pošiljaoca (podrazumijevano „ZEV upravnik"); pravo ime podešava super admin u /admin |
EMAIL_DAILY_SOFT_LIMIT | ne (podrazumijevano 180) | Meki dnevni limit e-mailova sa fakturama na nivou cijele platforme (Mailjet besplatni plan = 200/dan); važi samo uz EMAIL_PROVIDER=mailjet. Kad se dostigne, poruke ostaju u redu i šalju se sutra. |
MAX_UPLOAD_MB | ne (podrazumijevano 4) | Ostaviti na na Vercel-u — serverless Function-e odbijaju tijelo zahtjeva preko 4.5 MB bez obzira na ovu vrijednost |
DocumentBlob/AttachmentBlob), ne na disku ni u eksternom storage-u.DEPLOYMENT_TARGET ili slična platformska varijabla — ne postoji; svaka opcija
(storage, e-mail provajder, upload limit...) se bira nezavisno, kao iznad.GET /api/health vraća { status: "ok" | "error", version }, bez autentikacije i bez
detalja o konekciji — provjerava samo dohvatljivost baze (SELECT 1). Koristi ga i
docker-compose.yml (healthcheck za app servis) i svaka PaaS platforma koja radi probe.
npm run db:seed)| Uloga | Lozinka | |
|---|---|---|
| Predsjednik ZEV | [email protected] | Lozinka123! |
| Računovođa | [email protected] | Lozinka123! |
| Vlasnik (Ana Savić) | [email protected] | Lozinka123! |
| Vlasnik (Marko Jovanović) | [email protected] | Lozinka123! |
| Vlasnik/suvlasnik (Nikola Ilić) | [email protected] | Lozinka123! |
Seed ostavlja prijedlog P--02 otvoren za glasanje. Bez pravog e-mail
provajdera, lični link i verifikacioni kod postoje samo u outbox tijelu poruke
(NotificationMessage.body) — vidi npm run test:links niže za način da im se pristupi
bez ijedne izmjene produkcionog koda.
npm test # 62 Vitest testa (prava pristupa, glasanje, obračuni, uplate, planovi, audit)
npm run typecheck # tsc --noEmit
npm run lint # eslint
npm run test:e2e # Playwright smoke (zahtijeva pokrenut server + seed)
Testovi koriste TEST_DATABASE_URL (baza se resetuje pri svakom pokretanju).
npm run test:e2e (bez argumenata) sam pronalazi najnoviji link/kod u outbox-u i kroz
njega provede cijeli tok. Za ručno klikanje kroz UI u pregledaču:
npm run test:links # ili: docker compose exec app npm run test:links
Ispisuje link i verifikacioni kod za svaku nedavnu poruku pozivnice/ponovnog izdavanja,
zajedno sa trenutnim statusom tokena (aktivan/iskorišten/opozvan/zamijenjen) — poništeni
linkovi se time ne mogu pomiješati sa važećim. Radi samo kad su oba uslova ispunjena:
SHOW_TEST_LINKS="1" i EMAIL_PROVIDER="mock" (podrazumijevano uključeno u
docker-compose.yml za lokalni razvoj; nikad postavljati na pravom deployment-u — vidi
komentar u .env.example i src/server/notifications/testOutbox.ts).
EMAIL_PROVIDER=mock,
VIBER_PROVIDER=mock). Poruke se upisuju u outbox (NotificationMessage) sa
simuliranim događajima isporuke (sent/delivered/seen); kompletan tok sjednica i
glasanja radi bez stvarnih kredencijala. Viber i dalje nema pravi provajder — bot API
šalje poruke pretplaćenim korisnicima, pa automatsko objavljivanje u proizvoljne
privatne Viber grupe nije podržano zvaničnim API-jem.
EMAIL_PROVIDER=mailjet,
src/server/notifications/mailjetEmail.ts). Podešavanje:
.env postavite EMAIL_PROVIDER="mailjet", MAILJET_API_KEY,
MAILJET_API_SECRET i MAILJET_FROM_EMAIL (verifikovana adresa iz koraka 1)."sent" događaj, za razliku od mock
provajdera koji simulira i delivered/seen.retryFailed() postoji, ali
nema pozivaoca — zakazivanje je van obima dok se ne uvede platformski scheduler)./admin → „E-mail podešavanja
platforme": ime (npr. „ZEV upravnik"), da li poruke jednog ZEV-a nose i njegov naziv, i
listu dozvoljenih primalaca. Dok lista nije prazna, stvarna e-pošta ide samo tim
adresama/@domenima (ostale poruke dobijaju FAILED i ne šalju se ni kasnije)./admin za super admina) šalje fiksnu poruku na vlastitu ili upisanu adresu
(najviše 5 na sat po korisniku, 20 dnevno po ZEV-u) i prikazuje tačnu grešku provajdera./admin upisati svoju adresu u probnu listu →
u Vercel-u postaviti Mailjet varijable i EMAIL_PROVIDER=mailjet → redeploy → probna
poruka na svoju adresu → isprazniti listu. Mailjet besplatni plan: 200 poruka dnevno,
6.000 mjesečno. Detalji: .LEGAL_AND_FINANCIAL_ASSUMPTIONS.md §6).4FONT_DIR | ne | Override lokacije PDF fontova ako platforma ne poštuje outputFileTracingIncludes iz next.config.ts |
STORAGE_DIR | ne | Samo za nazad-kompatibilno čitanje dokumenata generisanih prije prelaska skladišta u Postgres — nebitno za nov deployment |
Plans/email-sender-name-and-test-email-plan.mdPlans/invoice-email-delivery-plan.md): vlasnik u Podešavanja →
Moji podaci bira „Dostavi mi račun putem e-maila" (predsjednik i računovođa mogu umjesto
vlasnika, uz napomenu i revizorski trag). Poslije toga se svaka faktura izdata na njegovo ime
(nova, korektivna) šalje kao PDF prilog na kontakt e-mail, a storno kao kratko obavještenje.
Izdavanje samo upisuje poruke u red; šalje se najviše 25 po pozivu, ostatak dugmetom „Pošalji
neposlate" na stranici serije. Ovo je jedini izuzetak od pravila „bez finansijskih podataka u
porukama": PDF dobija samo dužnik koji je dostavu izabrao, a tijelo poruke nema iznose.
Migracija 20261023100000_add_invoice_email_delivery se na produkciji pokreće ručno prije deploy-a.Attachment), ali upload UI
nije uključen u MVP obim.