Lalabase
티켓·문서·근무시간·고객대화를 한 곳에 모아 KI로 검색, 소프트웨어 기업 고객 프로젝트용, 오픈소스로 자체 서버·독일 클라우드에 배포
구조용 강철 제작·설치 업체를 위한 프로젝트 전달 플랫폼, 상세 설계 승인부터 인도 패키지까지 지원
The project delivery platform built for structural steel fabricators and erectors — from detailing approval to turnover package.
비즈니스TypeScript · JavaScriptGitHub @lorteezy87가동 상태 재확인 필요운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
A multi-tenant project-management platform purpose-built for structural
steel fabricators and erectors — tracking drawings, submittals, RFIs,
fabrication, deliveries, change orders, costs, and field operations from
detailing through closeout. Each company works in its own workspace
(organization); the drawings + submittals + RFI workflow is the product's
moat.README 전문 보기 ↗A multi-tenant project-management platform purpose-built for structural steel fabricators and erectors — tracking drawings, submittals, RFIs, fabrication, deliveries, change orders, costs, and field operations from detailing through closeout. Each company works in its own workspace (organization); the drawings + submittals + RFI workflow is the product's moat.
Reading order for new contributors:
- This README — get it running locally
ARCHITECTURE.md— system shape, tenancy, auth/RBAC, workflow conceptsTECH_DEBT.md— known issues + remediation pathsCLAUDE.md— agent-driven development conventions (deploy flow, branch model)
src/styles/tokens.css, the SteelBuild dual-theme system) plus a small
design-system module carry every surface, text and border colour. Tailwind is
installed and compiled (tailwind.config.js, @tailwind directives in
src/globals.css) and is used for layout/utility classes — but colours come
from tokens only, never a hardcoded hex. See the design-system rules in
CLAUDE.md.web-ifc wasm + three.js,
lazy-loaded) for the Detailing Control Center's 3D tab; pdf.js for drawings.steelbuild-pro.com and
www.steelbuild-pro.com; Cloudflare Workers remains for staging and PR
previews. Production release artifacts require five green jobs: ci,
secret-scan, supabase-drift, edge-typecheck, and commercial-postgres.
Vercel is retired.llm-proxy Edge Function
(currently OpenAI gpt-4o / gpt-4o-mini). Never call a provider from the browser.stripe-billing Edge Function.@sentry/react) with masked session replay.This rebuild covers the full fabricator/erector workflow, including drawings, shop release, production, logistics, field work, schedule, and commercial controls. Erection-only workspaces must retain relevant field workflows while fabrication capabilities are enforced server-side as well as in navigation. Proposed intelligence extensions include reviewed field-note drafts, scanned drawing intake with page evidence, schedule-blocker analysis, cited document answers and RFI drafts, and clearly labeled proposal/training visuals. They are roadmap items unless a specific feature is verified in source and hosted acceptance; AI output does not authorize release, clear holds, or approve engineering decisions.
A company signs up and creates a workspace (organizations table). The
workspace is the billing + invite + grouping unit; every project belongs to an
org (projects.org_id). Tenant isolation is enforced at the database layer —
the org boundary is wired into user_has_project_access (and therefore every
project-scoped RLS policy), into create_project, into storage upload paths,
and into the vendor / user-profile reads — so one tenant can never read
another's data. See
ARCHITECTURE.md.
The detailing/submittal flow has 8 derived workflow stages (7 stored sheet
stages). Submittals are the source of truth for workflow status; drawings
are document artifacts. See docs/architecture/drawing-workflow-dual-source.md.
Not Started → IFA → OFA → BFA → R&R → OFS → IFC → Released for Fab
New users are walked through this flow by a data-driven Getting Started
checklist on the project Dashboard that tracks the project's real progress
(upload drawings → create a submittal → raise RFIs → release for fab) and
deep-links to each step. It's separate from the data-setup onboarding
(OrgOnboarding first-run org wizard; Onboarding project create/import/seed).
See ARCHITECTURE.md for the full glossary
and the status×ball-in-court → stage mapping.
The calculator workspace responds to the available content width, including the space left beside the app sidebar. Crane-pick fields stack when needed, and its 3D view resizes with its container and the phone viewport. Virtualized command registers retain their columns in an aligned, keyboard-scrollable horizontal region instead of clipping the rightmost actions. These are source-level layout changes; the authenticated crane-pick route still needs rendered viewport acceptance on target devices.
Requires Node 24 and npm 11 (Node pinned in .nvmrc; run nvm use, which brings its bundled npm 11). CI installs with Node 24 / npm 11.
Older npm (10, bundled with Node 22) rejects the lockfile with an npm ci "not in
sync" error, because it resolves the miniflare sharp/undici overrides
differently. Don't regenerate the lockfile to fix that; switch Node.
npm ci
npm run dev
npm ci is the reproducible install path for the committed lockfile. Use
npm install only when intentionally changing dependency metadata.
Create .env.local with the two required variables:
VITE_SUPABASE_URL=https://<your-project>.supabase.co
VITE_SUPABASE_ANON_KEY=sb_publishable_...
Do not put provider API keys in VITE_* browser variables — all LLM and
billing secrets live server-side in the Edge Functions' environment.
| Command | What it does |
|---|---|
npm run dev | Start the Vite dev server |
npm run build | Production build to dist/ |
npm run preview | Serve the built bundle locally |
npm run lint | ESLint (quiet — warnings suppressed) |
npm run lint:fix | ESLint with autofix |
npm run typecheck | tsc --noEmit against tsconfig.json (TS) |
npm run typecheck:js | tsc --noEmit against jsconfig.json (JS/JSX) |
npm run typecheck:strict | strictNullChecks ratchet — all .ts/.tsx except the grandfathered list |
npm run typecheck:noimplicitany | noImplicitAny ratchet — all .ts/.tsx except the grandfathered list |
npm run check:no-new-js | Reject new JS/JSX source files on this branch |
npm test | Vitest run (unit + jsdom integration tests) |
npm run test:watch | Vitest in watch mode |
npm run test:e2e:foundation | No-backend desktop/mobile browser acceptance |
npm run perf:bundle | Check production bundle budgets after build |
npm run supabase:drift | Compare remote Supabase schema vs migrations (skips without token / ALLOW_SKIP=1) |
npm run supabase:delete-deprecated-fns | Dry-run delete of retired Edge Functions (DRY_RUN=0 to apply) |
src/
boot/ app bootstrap (AppProviders, AuthenticatedApp, AppRoutes, gates)
pages/ route-level screens (~75)
components/ feature-scoped UI (drawings/, financials/, viewer3d/, settings/, …)
hooks/ TanStack Query hooks + CRUD wrappers
api/ Supabase client (entities/auth/integrations/functions) + storage helpers
lib/ shared utilities, AuthContext, billing/, org/, ifc/, payapp/, backcharge/, field/
services/ deterministic domain engines (costRollup, marginRiskEngine, …)
utils/ shared deterministic helpers, including the typed PCC scoring engine
supabase/
migrations/ ordered SQL migrations (timestamped `YYYYMMDDhhmmss_name.sql`)
functions/ Edge Functions (llm-proxy, email-ingest, email-send,
project-export, stripe-billing, …)
public/ static assets, web-ifc wasm, pdf workers
Migrations live in supabase/migrations/ (timestamped
YYYYMMDDhhmmss_name.sql — the history was re-baselined on 2026-06-20 and
~190 legacy migrations are archived in supabase/migrations_archive/, so
inspect the directory rather than assuming a number; 123 files as of
2026-09-22). After a migration that changes the exposed schema, the SQL ends
with NOTIFY pgrst, 'reload schema'.
Do not apply migrations with supabase db push or the Supabase MCP
apply_migration. This Supabase project is shared with a sibling app, so the
remote ledger carries versions this repo does not own (42 of 130 as of
2026-09-22, catalogued in supabase/production-ownership-manifest.json) and the
CLI refuses; apply_migration stamps its own apply-time version, which is how
the ledger drifted in the first place. Migrations here are applied and stamped
by hand, and the committed filename must be the stamped ledger version.
Supabase drift check compares the two on every branch, so a stamp whose file
is unmerged turns main and every open PR red. Read the full procedure in
CLAUDE.md before applying anything.
Three role layers:
user_profiles.role ('admin' | 'user') — gates app-level admin
routes (e.g. /FeatureFlagsAdmin).organization_members.role ('owner' | 'admin' | 'member') —
governs billing, invites, and workspace membership. Helpers user_is_org_member,
user_org_role_at_least.user_projects.role ('owner' | 'admin' | 'pm' | 'field' | 'viewer') — governs project data + actions. 'owner' ≡ 'admin' (level 3).
Helpers user_has_project_access (now org-aware), get_my_project_role,
user_has_project_role_at_least.Front-end: useAuth() (user + global role), useOrg() (current workspace +
role), useProjectRole(projectId), usePermissions().can(). Member management:
OrgMembers (/OrgMembers — workspace team + tokenized invites) and
ProjectMembers (per-project access).
Account security. Self-serve password reset ("Forgot password?" →
emailed link → /update-password, gated at top precedence for the recovery
session) and change password (Settings → Profile → Security). Optional
TOTP MFA — enroll in Settings → Security; an aal1 session with a verified
factor is gated to a step-up challenge before entering the app. All via the
Supabase Auth API in AuthContext.
Settings is the signed-in user's personalization center. Preferences sync through the user's Supabase profile metadata and apply across the app: system, light, or dark theme; accent, font scale, contrast, motion, table density; date/time, number, currency, and measurement formats; sidebar mode, recents, keyboard hints, project-number visibility, and in-app alert/quiet-hour rules.
The My Workspace tab adds Project Manager, Field, Fabrication, and Executive presets with a review-before-apply summary, plus server-backed favorite modules and projects. Reset & Portability can export a versioned, allowlisted JSON preference file, validate an import before applying it, or restore individual sections or all defaults with a typed confirmation. These settings are presentation-only and never grant roles, permissions, project access, or other authorization.
Free / Pro / Business tiers (src/lib/billing/plans.ts). organizations.plan
is the entitlement anchor — only the Stripe webhook (service role) can change
it (a DB trigger blocks the client). Plan limits (projects, members) are
enforced server-side in create_project and accept_invitation. Billing page
at /Billing (stripe-billing Edge Function → Stripe Checkout / Portal).
Settings → System → Export Data produces a per-tenant JSON backup of every
project the caller can access — fetched through the RLS-scoped, audit-logged
project-export Edge Function and bundled client-side (src/lib/workspaceExport.ts).
Right-to-erasure (GDPR/CCPA). An owner-only "Danger Zone → Delete workspace"
action (Team page) permanently erases an organization — DB rows via the
hard_delete_organization RPC (with an append-only account_deletions audit that
survives the wipe), Storage objects, and orphaned auth users via the
account-delete Edge Function. Gated behind the account_deletion feature
flag (off by default) and a type-the-name confirmation.
Vitest runs pure helpers in node and component/integration tests in jsdom
(// @vitest-environment jsdom), with Supabase mocked. The 2026-10-08
73664ef16 CI run passed 8,193 tests across 842 files. The blocking
npm run test:e2e:foundation suite passed 76 desktop/mobile browser checks
without a backend. Authenticated Playwright scenarios need a configured login
fixture: e2e/mobile-overflow.spec.ts includes the exact
/CalculatorsHub?calc_tab=cranepick route at 360, 393, and 430px, but those
cases were listed, not run, at this checkpoint. The foundation pass does not
establish logged-in calculator viewport acceptance.
.github/workflows/ci.yml runs on configured push branches and pull requests
targeting the supported bases. The blocking ci job runs lint, the no-new-JS
gate, four typecheck gates (TS, JS/JSX, strictNullChecks, noImplicitAny),
Vitest, no-backend Playwright foundation acceptance, database helper/account
deletion/MFA checks, the production build, and bundle budgets. Production
release artifacts and PR previews also require secret-scan (gitleaks),
supabase-drift (the production ledger), edge-typecheck (released Edge
Functions), and commercial-postgres (commercial SQL and concurrent database
acceptance). A red required job skips the production handoff and preview.
After an authorized Sites promotion, the verification workflow compares both
public domains with the exact gated artifact. dependency-audit reports vulnerabilities
but is not a deployment prerequisite; optional authenticated Playwright
smoke runs separately. A concurrency group cancels redundant feature-branch
runs without interrupting a main release-artifact build.
Release and operations workflows beside it include
sites-production-verify.yml (manual
post-promotion exact-asset and optional authenticated smoke),
storage-backup.yml (nightly Storage
backup), supabase-deploy-reviewed.yml (manual, reviewed Edge Function deploy
for llm-proxy, project-export and stripe-billing), and
supabase-retire-deprecated.yml.
Feature work lands on a feature branch and is reviewed through a pull request. A
push to main runs ci, secret-scan, supabase-drift, edge-typecheck,
and commercial-postgres; only if all five pass does
prepare-sites-release build and upload the checksummed Site archive. It does
not publish. An authorized operator saves and deploys that exact archive through
Sites, then dispatches sites-production-verify.yml with the release run ID and
SHA. GitHub stores no reusable Sites credential. A red run creates no promotable
artifact, so production stays on the last good Site version. Rollback redeploys
the recorded prior saved Sites version. See
docs/runbooks/sites-release.md. Remaining gap: no
branch-protection required check (repo plan), so red/unreviewed commits can
still land on main even though they cannot deploy.
CLAUDE.md documents the full workflow + git-safety rules.
Edge Functions deploy separately from the web app. The reviewed path is the
manual supabase-deploy-reviewed.yml workflow (llm-proxy, project-export,
stripe-billing); others go via supabase functions deploy. Nine functions are
live in production as of 2026-09-22: llm-proxy, email-ingest, email-send,
stripe-billing, project-export, health, command-center-read,
command-center-session-handoff, account-delete. The repo also carries
staging-e2e-bootstrap (staging only) and legacy-app-files-copy (retired from
production 2026-09-21). Every previously deprecated function — sharepoint-proxy,
bluebeam-proxy, stripe-setup, stripe-webhook, stripe-worker, sheets-api
— has been deleted.
Staging. Rebuilt 2026-09-21 on a persistent Supabase branch
(ndyfjffsulfbwpmwdmic) behind the steelbuild-pro-staging Worker, deployed by
the deploy-staging-cloudflare job from the staging branch. It holds no
production data, Auth users, secrets or stored objects. Read-only and
disposable-mutation E2E jobs run against it. Details, including what the
schema restore did and did not cover, are in
docs/runbooks/staging-setup.md.
Current hosting boundary (2026-10-15). Production is Sites version 19 for
the project pinned by .openai/hosting.json. Its deployed source tree matched
GitHub main at 98bdf17ec9c9aeeaf0d993b8b56200d7927bb21f, and both custom
domains are active. CLOUDFLARE_ENABLED=false is intentional because the legacy
Worker no longer owns production routing. Future web releases use the gated
Sites artifact, authorized promotion, and exact-domain verification described
above. Source checks, an uploaded artifact, or a saved Site version alone are
not hosted-production evidence. Whole-app enterprise and monetization readiness,
provider delivery, backup restore, authenticated workflow/viewport acceptance,
and the build-tool advisory remain open.
Ops. A public, DB-aware healthcheck (GET /functions/v1/health → 200
{status:ok,db:ok} / 503 when Postgres is unreachable) is the uptime-monitor
target. Enterprise-readiness remediation status + owner action list live in
ENTERPRISE_READINESS_AUDIT.md,
docs/runbooks/owner-checklist.md, and the
Tier 1 split matrix
docs/runbooks/tier1-enterprise-status.md
(code-complete vs owner-only: PITR, Stripe Tax dashboard, branch protection, …).
The broader 2026-09-21 production-readiness audit — security, tenancy, data
correctness, performance, release process and store readiness, with a §9
reconciliation against current main — is
docs/audits/PRODUCTION_READINESS_AUDIT_2026-09-21.md.
The product ships as a web app today. Neither store build exists yet.
capacitor.config.ts, appId
com.steelbuildpro.app, webDir: dist). The ios/ Xcode project is
committed: npm run cap:sync copies the web build into it, and
npm run cap:open opens it in Xcode. Signing, archiving and App Store
Connect need a Mac with Xcode and can't run in CI/Linux. The runbook, including what's left before submission, is
docs/app-store/SUBMISSION.md.@capacitor/android is
not a dependency and there is no android/ directory. Play submission is a
from-scratch task, not a configuration change.Sentry is initialised in src/instrument.js (imported first in main.jsx):
error capture + performance tracing + masked session replay (maskAllText +
blockAllMedia, so replays never expose readable project/financial content).
DSN from VITE_SENTRY_DSN with a baked-in fallback. src/lib/telemetry.js stays
a local-only ring buffer (window.__sbpErrorLog); llm_telemetry is the
separate LLM-spend table.
feature_flags in Supabase is the only runtime authority. Every production flag
must exist in the typed catalog at src/config/featureFlags.ts and the catalog
seed migration. Admin UI is at /FeatureFlagsAdmin; global enablement and
administrator-managed per-user overrides are environment state, not committed
personal data. The retired command_ui presentation flag is no longer consumed
by runtime code. The eight remaining operational flags are read server-side via:
import { useFlag, useAllFlags } from "@/hooks/useFeatureFlag";
const show3dViewer = useFlag("viewer_3d");
Per-user overrides use feature_flags.user_overrides as a jsonb map and must not
contain personal email addresses in source-controlled seeds.
Module scope-cut gates (nav + route): deprioritized modules (Cost, advanced
Reports/Portfolio, Procurement, Risk, Quality suite extras, Resources, Closeout,
Email Inbox, Integrations, …) are hidden and deep-link-blocked unless their
module_* flag is on. Core steel workflow (Dashboard, Detailing Control Center,
RFIs, Work Packages / Piece Register / Fab, Schedule, Field, Projects, Settings)
stays always on. Config: src/config/moduleGating.js + useModuleAccess.
web-ifc + three) lazy-loaded into the
Detailing Control Center's "3D Model" tab behind the viewer_3d flag. The
web-ifc.wasm is version-pinned and copied to public/wasm/ by a Vite plugin
on every build — a worker/package mismatch silently yields zero geometry. (The
old @thatopen/components IFC/BIM stack was removed to shrink the bundle.)
Fab color mode paints linked lots from pieces.lifecycle_status (Production /
Logistics / fab-release invalidate canonical-pieces-3d). Measure snap targets
1/16″. Zoom/orbit do not "run out of gas" (unbounded camera).src/pages/DrawingViewer.jsx defaults to a browser-native <iframe>;
a pdf.js canvas mode is available via the toolbar toggle. Multi-sheet PDFs rely
on correct drawings.pdf_page./DocumentControl) — read-only intake desk: drop a
drawing PDF and get its title block, its place in the project's whole live
register, what changed against the sheet of record, seal / signature and
approval findings, and a database-ready JSON payload. Writes nothing;
extraction runs in the browser. The engine is src/lib/docControl/, which the
revision-upload wizard also renders — the difference is register scope ("is
this sheet in THIS set" vs "anywhere on this job").?targetSetId=),
revision Attach / Not now confirm, status → BIC/dates suggest strip
(src/lib/submittalLinkGlue.ts).--sbd-bg-panel*)
and .sbp-opaque-popout for menus (no frosted glass wash-out on selects).ARCHITECTURE.mdTECH_DEBT.mddocs/audits/PRODUCTION_READINESS_AUDIT_2026-09-21.mddocs/app-store/SUBMISSION.mddocs/runbooks/tier1-enterprise-status.mdCLAUDE.md · concurrent claims → AGENT_CLAIMS.mdARCHITECTURE.md#domain-workflow.claude/agent-memory/construction-pm-dev/MEMORY.md