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,即可驗證所有權並自行管理介紹。
一分鐘完成驗證Syncs project hours to Airtable.
翻譯準備中
取自儲存庫 README
正在載入完整 README。 以下為已儲存的摘錄。
Next.js web app (Vercel) hosting three internal tools:
• Hours Sync (/) — syncs OEG ERP time report hours into the Airtable
DPP Projects → Hours table.
• Budget Sync (/budget) — syncs Project Contract Status budgets into
the Airtable DPP Projects → Budgets table.
• Bid Pricing (/pricing) — extracts historical bid-tab pricing,
standardizes line items against a Master Catalog (AI-assisted via Claude),
and computes Weighted Average/Median/Low/High pricing per item. See
§ Bid Pricing Estimator below.
Each tool follows the same upload → dry-run preview → Confirm pattern.檢視完整 README ↗Next.js web app (Vercel) hosting three internal tools:
/) — syncs OEG ERP time report hours into the Airtable
DPP Projects → Hours table./budget) — syncs Project Contract Status budgets into
the Airtable DPP Projects → Budgets table./pricing) — extracts historical bid-tab pricing,
standardizes line items against a Master Catalog (AI-assisted via Claude),
and computes Weighted Average/Median/Low/High pricing per item. See
§ Bid Pricing Estimator below.Each tool follows the same upload → dry-run preview → Confirm pattern.
npm install
cp .env.example .env.local # fill in the values below
npm run dev # http://localhost:3000
Airtable token: create one at https://airtable.com/create/tokens. Required scopes on the DPP Projects base (Hours/Budget Sync) and the Bid Pricing base (Bid Pricing Estimator):
data.records:readdata.records:write.env.example (Airtable, and — if
using Bid Pricing — Anthropic + Supabase + the Bid Pricing base/table ids).Every push to main re-deploys automatically.
Optional password for the Bid Pricing tool. Add APP_PASSWORD (and optionally
APP_USERNAME, default oeg) in the Vercel project's environment variables and
redeploy. The browser then asks for the username/password before showing /pricing
or calling /api/pricing/*. If APP_PASSWORD is not set the tool stays open.
/workflows (embedded in SharePoint) and the other tools are not affected.
npm i -g vercel
vercel # follow prompts
vercel env add AIRTABLE_API_KEY # paste your token when prompted
vercel --prod
Drop the .xlsx report on the page. The file is sent to /api/plan.
The server:
Tracking = true) from Airtable.EntryDate.CREATE, UPDATE, SKIP-TODAY, SKIP-NOERP,
or NOMATCH — for every tracked project.The browser renders the plan as a table. You review it, then click
Confirm Sync to call /api/sync, which executes the writes.
Ported from a Google Colab notebook ("OEG Unit Price Update"). Two modes on
one page (/pricing):
Ingest — upload bid-tab .xlsx files (multiple at once). Each file's
line-item × contractor prices are parsed and added to a permanent history
table in Supabase (bid_history) — only new files need uploading, ever;
already-ingested rows are skipped by a dedup key. Descriptions that don't
resolve against the Master Catalog / verified Living Matches get scanned and
batch-matched by Claude (lib/aiMatch.ts), then reviewed in-app
(approve/reject/correct) before being saved as verified mappings.
Estimate — computes Count/Weighted Avg/Median/Low/High per Master Catalog item from the full bid history (10% outlier trim when ≥5 samples, same as the original notebook), writes the results back onto the Airtable Master Catalog records, and offers a CSV download.
Data storage split (see .env.example for the env vars):
Master_Catalog and Living_Matches tables. Must be
created and seeded manually (see below) before this tool will work.bid_history table,
avoids Airtable's ~50k record ceiling). Run this DDL in the Supabase SQL
editor once:
create table bid_history (
id bigint generated always as identity primary key,
source_file text not null,
project_name text,
bid_date text,
contractor text not null,
original_description text not null,
qty numeric not null,
unit text,
price numeric not null,
ingested_at timestamptz not null default now(),
constraint bid_history_dedup_key
unique (source_file, contractor, original_description, qty, price)
);
create index bid_history_source_file_idx on bid_history (source_file);
create index bid_history_original_description_idx on bid_history (original_description);
alter table bid_history enable row level security;
Airtable base setup — create a base (e.g. "Bid Pricing") with:
Master_Catalog: Master_Item_Name (primary), Standard_Unit, Count,
Weighted_Avg, Median, Low, High, Last_Estimated_Date. Seed this
with your real catalog items — an empty catalog means everything resolves
to "REVIEW".Living_Matches: Raw_Description (primary), Raw_Unit,
AI_Guessed_Master_Item (single line text — an immutable audit trail of
Claude's raw guess, kept as text since it may not always match a real
catalog item), Master_Item (Link to another record → Master_Catalog,
single record — the operational field the app actually reads; a link
keeps matching robust to catalog renames, unlike a text copy of the name),
Confidence (single select: High/Medium/Low), Status (single select:
Pending/Verified/Ignored).app/
page.tsx — Hours Sync UI (upload → preview → confirm → done)
budget/page.tsx — Budget Sync UI
pricing/ — Bid Pricing Estimator UI (Ingest / Estimate tabs)
api/
plan/, sync/ — Hours Sync routes
budget-plan/, budget-sync/ — Budget Sync routes
pricing/ — Bid Pricing routes (harvest, ai-match,
living-matches review, estimate, ...)
lib/
erpCodes.ts — TITLE_MAP, codeMatches(), aggregateHours()
parseReport.ts — SheetJS XLSX parsing (Hours Sync)
parseBudget.ts — SheetJS XLSX parsing (Budget Sync)
parseBidTab.ts — SheetJS XLSX parsing (Bid Pricing bid tabs)
pricingMath.ts — Weighted Avg/Median/Low/High computation
aiMatch.ts — Claude batch line-item matching
airtable.ts — Airtable REST API wrappers (shared)
airtablePricing.ts — Bid Pricing base/table ids + dictionary map
supabase.ts — Supabase client + bid_history helpers
types/
index.ts — shared TypeScript types
lib/erpCodes.ts.TITLE_MAP (key = lowercase ERP title, value = Airtable field name):
"new erp title": "Airtable Field Name",
ALL_POSITIONS in the same file.| ID | |
|---|---|
| Base | app5bWT0n7TPWHWWy |
| Projects table | tblWeL8UyZm5pRf6h |
| Hours table | tbl1vOP20ZQUg6nG6 |
Do not write to formula/rollup fields: Total Hours, IfCurrent,
LatestEntryDate, CAD Hours, Design Hours, PM Hours, PE Hours,
DM Hours, Project Name.