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,即可驗證所有權並自行管理介紹。
一分鐘完成驗證正在載入完整 README。 以下為已儲存的摘錄。
A business directory for graduates of AsiaWorks training. Graduates list their businesses, the public searches and
browses them, and graduates find each other to work together. The interface is in Bahasa Indonesia.
Built as one Next.js app (React, TypeScript, Tailwind) that talks straight to Supabase from the browser. There is no
server code of our own: every permission is enforced inside Postgres, so the app stays small and light.檢視完整 README ↗A business directory for graduates of AsiaWorks training. Graduates list their businesses, the public searches and browses them, and graduates find each other to work together. The interface is in Bahasa Indonesia.
Built as one Next.js app (React, TypeScript, Tailwind) that talks straight to Supabase from the browser. There is no server code of our own: every permission is enforced inside Postgres, so the app stays small and light.
| Route | What it is |
|---|---|
/ | Home: banner, shortcuts, search with map and list, browse by industry or city, latest Peluang, perks, events |
/bisnis/[id] | A business page |
/peluang | Partner requests posted by graduates |
/acara | Events with RSVP, collaboration stories, "offer to host" |
/lulusan | Meet Graduates: every live business as a card |
/daftar | Sign-up in three short steps |
/masuk | Member login |
/akun | Member dashboard: Peluang, Bisnis, Koneksi, Akun |
/staff | Staff login and console |
The banner on the home page is one slider, newest first. Only staff put a banner up, from the console: an announcement, or an ad for one business (members cannot submit ads). It moves on every five seconds until someone slides it by hand. A banner with a picture shows only the picture, so its message belongs in the picture: 1200 × 400 fits (wide screens trim a little off the top and bottom). A banner without one shows its title and text on a brand backdrop.
Needs Node 20+ and Docker.
npm install
cp .env.example .env.local # then put in the local values shown below
npm run db:up # local Supabase: Postgres, Auth, REST, Storage on http://localhost:54321
npm run db:apply # tables, rules and functions
npm run seed # optional: demo businesses, events, members
npm run dev # http://localhost:3000
Local values for .env.local: the URL is http://localhost:54321, and the two keys are the x-anon-key and
x-service-key lines at the top of supabase/local/docker-compose.yml (Supabase's public demo keys, local only).
After seeding, every demo account uses the password asiaworks123:
[email protected] (sign in at /staff)[email protected] (sign in at /masuk)npm run db:reset wipes the local database and applies the schema again.
Create a new Supabase project. Use a project of its own: the schema creates tables such as profiles and events.
Open the SQL Editor, paste all of supabase/migrations/20261001000000_init.sql, run it once.
Authentication settings:
https://your-domain/masuk and https://your-domain/daftar as redirect
URLs (used by "Lupa kata sandi" and email confirmation).Set NEXT_PUBLIC_SUPABASE_URL and NEXT_PUBLIC_SUPABASE_ANON_KEY where the site is hosted.
Make the first staff account: sign up at /daftar (the first step is enough), then run this in the SQL Editor and
sign in at /staff:
update public.profiles set role = 'staff'
where id = (select id from auth.users where email = '[email protected]');
A project that already has the schema. The migration file always holds the whole, current schema, for a new
project. When the schema changes after a project was set up, the change is also in supabase/upgrades/, one file per
change, named by date. Paste the files that are newer than your project into the SQL Editor, oldest first. Each is
safe to run twice and deletes nothing.
Check the rules on the hosted project. Put the project's URL, anon key and service role key in a file of its own
(for example .env.hosted, same three names as .env.local; keep it private) and run
node --env-file=.env.hosted scripts/check.mjs. It signs up its own test accounts, proves each rule through the API
and removes everything it made. One step is skipped there, because it reads the database directly.
Deleted pictures on hosted Supabase. A deleted picture is gone from storage at once. Supabase's CDN can go on answering at the picture's direct address for up to a minute, and the browser of someone who already opened it keeps its own copy for up to an hour.
The whole feature is one folder, app/(aw). It is a route group, so it adds the routes above without changing any
existing one, and it brings its own layout (fonts, session, header, bottom bar).
The host site needs the Next.js App Router and Tailwind CSS 4.
app/(aw) into the site's app folder.@import "tailwindcss";, add @import "./(aw)/_lib/theme.css";.
The file only adds tokens and utilities with their own names. It does not reset Tailwind's defaults.
A site that does not build with Tailwind 4 yet installs it first (npm i -D tailwindcss @tailwindcss/postcss,
plus the PostCSS plugin as in this project's postcss.config.mjs).npm i @supabase/supabase-js leaflet lucide-react and npm i -D @types/leaflet.NEXT_PUBLIC_SUPABASE_* variables and run the SQL file on the Supabase project.Things to know when merging:
app/(aw)/layout.tsx renders the directory's own header and footer. A site with its own header can drop
<Header /> and <Footer /> from that file (keep <BottomBar />, it is the phone navigation). Those two hold the
only desktop links to the four pages, Masuk and Dasbor, so add those links to the site's own header./acara is taken, rename that folder inside app/(aw), then search app/(aw) for the old
path and replace it. The paths are written out in the links of about twenty files, not in one place.app/(aw)/page.tsx, at /. A site with its own home page moves that file into a folder
(say app/(aw)/direktori/) and replaces the "/" links in app/(aw) with the new path.app/not-found.tsx belongs to this demo project, not to the folder. A host site keeps its own.page.tsx,
layout.tsx, [id]), about twenty files import next/link, next/navigation or next/font, and the Supabase keys
are read from process.env.NEXT_PUBLIC_*. The components themselves are plain client components, so the work is
mapping the routes to the host's router and swapping those imports and the two variable names.app/(aw)/
layout.tsx fonts, session provider, header, footer, bottom bar
_lib/ supabase client, session, queries, formatting, image upload, design tokens (theme.css)
_components/ ui kit, site chrome, map, cards, member actions, login form
_components/akun/ dashboard tabs
_components/staff/ staff console sections
page.tsx the home page
bisnis/[id]/ peluang/ acara/ lulusan/ daftar/ masuk/ akun/ staff/ one page.tsx each
supabase/
migrations/20261001000000_init.sql the whole database: tables, RLS, grants, feeds, RPC, storage rules
local/ Docker Compose for a local Supabase
scripts/
check.mjs proves the rules below through the real API (npm run check)
seed.mjs demo data through the real flows (npm run seed)
import.mjs the Expo Google Form's answers (CSV) into accounts and listings; prints the plan unless --write
serve.mjs, screenshot.mjs design workflow: dev server on :3000 and page screenshots
Roles: visitor (no account), member (signed up), graduate (member whose program and batch staff approved), staff. The browser only holds the anon key, so these rules live in the SQL file, not in the UI.
search_businesses() and the *_feed views. Each of those checks that the listing
is approved, has the owner's consent, and is switched on, so a suspended or switched-off listing disappears from
search, the map, Peluang, promos, stories and ads at once.submit_business) and a moderator's approval (moderate).
Status columns cannot be written directly; column grants leave them out. moderate also refuses to publish a
listing, a Peluang or a hosted event while its owner is not a verified graduate. For a demo, staff can switch on
"Auto Approve Bisnis", "Auto Approve Peluang" and "Auto Approve Promo" (Moderasi): what is sent then goes live
at once, and the audit log says so.graduate_feed. That view only holds verified graduates who have a
live business or an open Peluang, so signing up alone puts nobody on the site.verify_graduate), or from the demo switch "Auto Approve Graduates
Request" in the staff console. Withdrawing it takes that person's listings, Peluang and hosted events down.save_profile).auth.users, not encrypted by this app, and reaches another member
only on an accepted Hubungkan request.area mode the database rounds the point to about 1 km before storing it.
"Online saja" hides every location.npm run check exercises all of this as real users and fails loudly if a rule stops holding.
Marked with ponytail: in the code. Fine for the 35 to 100 people this serves, with the upgrade path noted.
search_businesses returns one page of 200 rows. Add keyset paging when the directory outgrows it.audit_log; add a date filter when needed.payments table and its rules are in place. To switch on, connect a provider and let its server-side webhook
insert into payments (purpose takes a fixed code, 'ad' today); browsers have no insert right there on purpose.user_id becomes null. The audit log keeps that
something was done and drops the reason staff typed. Delete accounts from the staff console (Privasi): that route
also removes the stored files and the person's entries in Supabase Auth's own log, which a deletion from the
Supabase dashboard does not.audit_log by database triggers and staff RPC, and so is every approval made by
the Auto Approve switch, one row per person.