Lalabase
티켓·문서·근무시간·고객대화를 한 곳에 모아 KI로 검색, 소프트웨어 기업 고객 프로젝트용, 오픈소스로 자체 서버·독일 클라우드에 배포
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기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.