Synaplan
기업을 위한 오픈소스 AI 플랫폼
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
메이커가 쓴 소개는 위의 한 줄이 전부입니다. 더 자세한 내용은 저장소 README에서 읽을 수 있습니다. 저장소 README ↗
README 전체를 불러오는 중입니다.
README 전문 보기 ↗Internal operations platform for Team Charlie at STR Assistance (Module 1.1).
Built with Next.js 14 (App Router), TypeScript, Tailwind CSS, Prisma + PostgreSQL, NextAuth, Framer Motion, anime.js, and React Three Fiber.
/shift-schedule): the team's real weekly roster — Morning
(08:00–17:00), Evening (17:00–01:00), Night (00:00–08:00), and Backup (19:00–03:00)
shifts, fully editable in Settings. A week-by-week grid grouped by shift, each
employee's day marked Working/Weekend/Leave with optional per-day time overrides and
notes, a daily headcount row, a "Copy Last Week" action, and an optional 3D "Shift
Ring" hero visualization showing the selected date clearly with employee chips
arranged around a 24-hour arc.components/ui/select.tsx, built on Radix) used for every
select in the app/knowledge-base): lightweight Airbnb listing
preparation tool for client onboarding. Bulk import internal property names +
Airbnb URLs, run best-effort public listing extraction, review/fill operational
fields, and export CSV for Google Sheets / NotebookLM. This intentionally does not
add embeddings, chatbots, or a heavy AI knowledge system inside Charlie HQ.npm install
cp .env.example .env
Fill in:
DATABASE_URL — a PostgreSQL connection string (local Postgres, Supabase, Neon,
Railway, etc. all work)DIRECT_URL — only needed if DATABASE_URL points at a connection pooler (e.g.
Supabase's pgbouncer/session-pooler port 6543); set this to the non-pooled/direct
connection instead (port 5432). If you're on a plain direct connection, just set it
to the same value as DATABASE_URL — Prisma needs a direct connection to run
db push/migrations.NEXTAUTH_SECRET — generate with openssl rand -base64 32DISCORD_CHECKIN_WEBHOOK_URL / DISCORD_CHECKOUT_WEBHOOK_URL — create two Discord
webhooks (Server Settings → Integrations → Webhooks) pointed at your check-in and
check-out channels. These are read server-side only and are never sent to the browser.npm run db:push # creates tables from prisma/schema.prisma
npm run db:seed # seeds Team Charlie, users, clients, shift types, this week's roster, tasks
db:seed is idempotent — running it again after the app has been used will not
duplicate the seeded rows (it upserts by stable ids).
npm run dev
Visit http://localhost:3000. Seeded logins (password charliehq123 for all):
[email protected] — Admin[email protected] — Team Lead[email protected] — Employee[email protected] — EmployeeImport this repository into Vercel with the project root set to the repository root.
The default Next.js framework preset and build command are sufficient; npm run build
generates the Prisma Client before compiling Next.js.
Add these environment variables in Vercel for the Production environment:
DATABASE_URL — Supabase pooler URL, normally port 6543 with pgbouncer=trueDIRECT_URL — Supabase direct database URL, normally port 5432NEXTAUTH_URL — the deployed Vercel URLNEXTAUTH_SECRET — a new random production secretTEAM_TIMEZONE and NEXT_PUBLIC_TEAM_TIMEZONE — normally Asia/DhakaDISCORD_CHECKIN_WEBHOOK_URL and DISCORD_CHECKOUT_WEBHOOK_URL — optional webhooksBefore the first production deployment, apply the Prisma schema to the production
database with npm run db:push using the production environment values, then run
npm run db:seed once if the database is empty. Do not commit .env or place real
credentials in .env.example.
app/
(app)/ # authenticated route group (shared sidebar layout)
dashboard/
shift-schedule/
tasks/
attendance/
[userId]/ # per-employee history
clients/
[id]/ # per-client workspace
issues/
settings/
api/ # route handlers (server-only business logic)
login/
components/
layout/ # sidebar, mobile nav
dashboard/ shift-schedule/ tasks/ attendance/ clients/ issues/ settings/
ui/ # button, card, badge, dialog, select primitives
lib/
services/ # task-generation.ts, attendance.ts, shift-schedule.ts
queries/ # server-side data-fetching helpers
auth.ts # NextAuth config + role permission map
session.ts # getCurrentUser()/getCurrentUserOrNull() — the one place
# Server Components/routes read the session from
discord.ts # server-only Discord webhook sender
time.ts # timezone-safe date + week helpers (Asia/Dhaka by default)
validations.ts # Zod schemas
prisma/
schema.prisma
seed.ts
Task can
be marked isRecurringTemplate: true with a repeatMode/repeatDays, and
lib/services/task-generation.ts spawns a plain (non-template) Task row for each
future day it's due. Editing a generated instance never mutates the template it came
from, and editing the template only affects instances generated after the edit.ShiftType (Morning /
Evening / Night / Backup — admin-editable, not hardcoded) and ShiftAssignment (one
row per employee per specific calendar day: Working / Weekend / Leave, with optional
per-day time overrides) together model the team's actual weekly roster.
lib/services/attendance.ts reads expected check-in/check-out times from today's
ShiftAssignment — a day marked Weekend/Leave, or with no assignment, has no
scheduled time, so nothing is marked "late" against nothing.lib/services/attendance.ts always writes the attendance
record to Postgres before attempting the Discord webhook call. If Discord fails, the
record is kept with discordCheckInSynced: false and the error message stored, and an
Admin/Team Lead can retry from the Attendance page — a Discord outage can never
destroy a check-in/check-out.lib/time.ts, which reads TEAM_TIMEZONE (defaults to Asia/Dhaka).lib/auth.ts permissions map) and
are enforced server-side in every API route, not just hidden in the UI.lib/session.ts's getCurrentUser() (redirects to /login on a null session) or
getCurrentUserOrNull() (for API routes that need to return 401 instead) — avoids the
fragile session!.user pattern that could throw on refresh/direct-visit races.User, Client, Task, Issue,
ShiftAssignment) is scoped by teamId (via its user/team relation). Adding
Alpha/Bravo/Delta later means seeding more Team rows and building their dashboards —
it does not require restructuring Team Charlie's data.Airbnb/Guestly/WhatsApp/ClickUp/Zillow API integrations, payroll, leave management, full HR, advanced analytics, AI messaging, and the full Perfect Stay LTR/STR workflow. Perfect Stay and Jack are seeded as placeholder client workspaces only, as specified.
generateRecurringTaskInstances() / refreshOverdueTasks()
on a timer.lg breakpoint and never
blocks the 2D grid, which is the real day-to-day tool..env.example for future use
but the current implementation uses webhooks (simpler, sufficient for one-way
notifications).