Synaplan
기업을 위한 오픈소스 AI 플랫폼
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기메이커가 쓴 소개는 위의 한 줄이 전부입니다. 더 자세한 내용은 저장소 README에서 읽을 수 있습니다. 저장소 README ↗
README 전체를 불러오는 중입니다.
README 전문 보기 ↗Compliance and practice-management platform for an accounting firm: client portal, staff dashboard, service master, smart forms, ledger, payroll and corporate secretary modules. Next.js 14 (App Router) on Vercel, PostgreSQL behind it.
| Part | Where |
|---|---|
| The app | Vercel project, production on the main branch |
| The database | Neon (PostgreSQL), created from the Vercel project's Storage tab. It holds everything: firms, users, clients, forms, ledgers, payroll and every uploaded file. |
| Login sessions | Signed with JWT_SECRET from the project's environment variables |
Nothing else is needed. There is no Supabase, Turso or SQLite in the live setup, and the app refuses to connect to a Supabase address even if one is left in the environment variables (it logs which variable to delete). Nothing is stored on the web server's disk: Vercel's disk is read-only.
DATABASE_URL, DATABASE_URL_UNPOOLED, or the same names with a prefix
you choose). If it says a DATABASE_URL already exists, delete the old
one under Settings → Environment Variables first. The app only ever
uses Neon addresses (pooled first) and ignores any other cloud database.JWT_SECRET with a long random value (40+ characters), then redeploy.
Without it, sessions are signed with a built-in development value that
everyone who can read the source knows.Then open /login. The first login on a fresh database takes a few seconds:
the app creates every table (from src/db/schema.sql and the migrations in
src/db/migrations) and seeds the demo accounts, then signs you in.
The seed creates demo accounts; the login page lists them. Every seeded
account uses the password shown there. Change them (or remove the demo block
from src/app/login/page.tsx) before real client data goes in.
psql: copy DATABASE_URL from Vercel →
Settings → Environment Variables and run psql "<that value>". Treat that
value like a password.tax_intake_*: answers, their full change history, records, documents, review items, frozen submissions), accounting ledgers, payroll, corporate secretary
(cs_*), settings, and schema_migrations (which migration files have
been applied).pg_dump "<DATABASE_URL>" > backup.sql) before relying on it.src/db/seed-reference.ts, data in src/db/reference/). Sample content that earlier one-off
scripts created (sample corporations, sample ledger entries, sample forms) is demo data and is not
created. Real data from a previous database is brought over with Platform → Import data (below).document_blobs table, next
to the row that describes them, and are served by /api/documents/<id>/download after a permission
check. The limit is 4 MB per file because Vercel rejects larger request bodies.Signed in as a platform admin, open Platform → Import data. Paste the old database's address (for a
Supabase project use the Session pooler address from Connect, with the database password filled in), press
Check the old database, choose Replace (empties this database first; you must type REPLACE) or Add
(keeps what is here, skips rows that already exist), and press Start copying. The page copies table by table
with a progress bar and finishes with a report comparing the row counts of both sides. After a Replace, sign in
again: the accounts now come from the old database.
How it stays exact (src/lib/db-import.ts): values are copied as text so the database converts them to the
column's own type; only columns that exist on both sides are copied (an old database that lacks a newer column,
or has an extra one, still imports and the page warns about what is not copied); tables go in foreign-key order
and a row whose parent has not arrived yet is parked and placed at the end; counters for new records are moved
past the highest copied id. The address is used for the one request, never stored, logged or sent back. It refuses
to import a database into itself and refuses a Replace when the old database has no active platform admin.
Uploaded files are not in the old database (they were on a disk); only their records are copied.
Tested by tests/verify/import.py and tests/verify/import_browser.cjs.
| Name | Purpose |
|---|---|
DATABASE_URL | The Neon connection string, added by Vercel when Neon is connected. Prefixed variants (DATABASE_POSTGRES_URL, *_URL_UNPOOLED, ...) are tried too, pooled Neon addresses first. A Supabase address is never used. A local PostgreSQL address also works for development and tests. |
JWT_SECRET | Signs login sessions. Required in production. |
CRON_SECRET | Lets Vercel's scheduler run the daily jobs (/api/cron/*). Any long random value; Vercel sends it automatically once it exists. Without it only a signed-in platform admin can run those jobs. |
See .env.example.
cp .env.example .env.local # then point DATABASE_URL at a local Postgres
npm install
npm run dev # http://localhost:3000
The schema installs itself on the first request. To install it ahead of time, or to check a database by hand:
node --env-file=.env.local scripts/db-setup.js
src/db/schema.sql is the base schema.src/db/migrations/NNN_name.sql are applied after it, in file-name order,
each exactly once; applied names are recorded in the schema_migrations
table.src/db/migrations/. It is bundled
automatically (src/db/migrations/index.ts) and runs on the next deploy's
first request, or on demand with POST /api/migrate.src/lib/db.ts waits for the schema before every query, so no route needs
to think about it.npm run build / npm start — production build and servernpm run lintnpm test — Playwright tests (tests/)