Javis OS
Javis OS는 기업가를 돕는 에이전시 AI로, 업무를 지원하고 함께 성장합니다
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기SPM Scrum group project 2026. This project focuses on 20 core features of a event management application.
저장소 README에서 가져옴
README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
Event planning and venue booking system for ConnectSphere Event Services,
built by Group 7 for IS212 Software Project Management.
Live app: (deployed from
main; sign in with a seeded account below).
ConnectSphere replaces event planning by email and spreadsheets with one
system, where every event has one status, one assigned Coordinator, and
arrangements that can't clash:README 전문 보기 ↗Event planning and venue booking system for ConnectSphere Event Services, built by Group 7 for IS212 Software Project Management.
Live app: https://spm-group7-connect-sphere.vercel.app (deployed from
main; sign in with a seeded account below).
The live app is the team's development environment: it is where we build, test and coordinate the project, and it holds only seeded test accounts and demo events. It isn't a service for customers, and every page says so (SCRUM-237).
ConnectSphere replaces event planning by email and spreadsheets with one system, where every event has one status, one assigned Coordinator, and arrangements that can't clash:
Week 7 added two more roles:
Release 1 covers the twenty features in the Week 4 project instructions, and
Sprint 3 adds the Week 7 changes. The full picture (all seven roles, the event
lifecycle, scope) is in docs/product-context.md.
Course material: the customer briefing, the Week 4 project instructions
(the twenty Release 1 features and the grading rubric) and the customer's Q&A
answers are in the team's
shared Google Drive folder.
The repository already reflects them: the stories in docs/backlog/ quote
the customer where it matters, so you rarely need to open the folder.
| If you want to… | Read |
|---|---|
| Run the app | Getting started, below |
| Demonstrate the core workflows with the seeded accounts | docs/demo.md |
| Know what we are building and for whom | docs/product-context.md |
| Check a story's acceptance criteria | docs/backlog/SCRUM-n.md (the key is in your branch name) |
| See the planned test cases for a story | docs/testing/SCRUM-n.md |
| Build a feature and open a pull request | CONTRIBUTING.md |
| Know why something is built the way it is | docs/adr/ |
| Add a column or table | docs/data-model.md |
| See each sprint's commitment and outcome, how we estimate, and the Definition of Done | docs/scrum/ |
| Work with an AI coding assistant | CLAUDE.md |
Next.js (App Router) · TypeScript (strict) · Tailwind CSS · shadcn/ui · Prisma · PostgreSQL · Zod · Auth.js (NextAuth v5) · Vitest · Playwright · GitHub Actions.
Exact versions are pinned in package.json (no caret ranges).
From a clean laptop this takes about ten minutes. The team shares one live
Supabase database (project connectsphere, ref cczgpvrwmgirvryqecpb,
Singapore), so you need no local database to run the app.
.nvmrc pins it, so run nvm use (or
fnm use). CI and Vercel both run Node 24.# 1. Install dependencies (this also generates the Prisma client)
npm install
# 2. Create your local env file
cp .env.example .env
# Replace <PASSWORD> in both database URLs. Keep the session pooler on
# port 5432 exactly as given; .env.example explains why not 6543 and why
# not db.<ref>.supabase.co. Then set AUTH_SECRET to any 32-byte string:
# npx auth secret (writes it for you) or
# openssl rand -base64 32
# 3. Apply any pending migrations to the shared database
npm run db:deploy
# 4. Load the seed data (idempotent: deletes nothing, but resets every
# seeded row to its seed values)
npm run db:seed
# 5. Run the app
npm run dev
Open http://localhost:3000. You'll be redirected to /login.
Never run
npm run db:resetwhile.envpoints at Supabase. It drops and rebuilds the schema, which wipes the whole team's data.db:resetis for the local Docker database only. On the shared database,db:deployanddb:seedare all you ever need.
.env points at the shared database, so anything that writes test data or
drops tables runs against a local Postgres instead: the integration tests,
test:coverage, the e2e specs, db:migrate and db:reset. Point the
terminal at Docker first, so a forgotten .env can't send them to Supabase:
docker compose up -d
export DATABASE_URL="postgresql://connectsphere:[email protected]:5432/connectsphere?schema=public"
export DIRECT_URL="$DATABASE_URL"
npm run db:reset # LOCAL ONLY: drop, migrate, seed
npm run test:coverage # likewise test:integration, test:e2e, db:migrate
In PowerShell, set $env:DATABASE_URL and $env:DIRECT_URL instead. Use
127.0.0.1, not localhost: on Windows with Docker Desktop, localhost
resolves to IPv6 first, and every parameterised query then takes about 40 ms
instead of 1 ms, so the integration tests run ten times slower and the
race tests (e.g. SCRUM-161's TC-161-12, SCRUM-75's TC-75-11) time out. The
integration tests skip unless DATABASE_URL is localhost or 127.0.0.1, and so do the e2e
specs that guard with usesLocalDatabase. Some older e2e specs (for example
e2e/events.spec.ts) write without that guard, so never run test:e2e
with .env pointing at Supabase.
Offline, the same exports let you run the app against Docker too.
Postgres 13 or newer is required. The schema uses the
btree_gistextension (the migration creates it) for the constraints that make venue double-booking impossible. Supabase (Postgres 17) and thepostgres:16Docker image both include it.
Every seeded account uses the password Password123!:
| Role | Why it exists | |
|---|---|---|
[email protected] | Event Organiser | Owns most seeded events |
[email protected] | Event Coordinator | Assigned to most seeded events |
[email protected] | Venue Staff | Decided the seeded venue bookings |
[email protected] | Venue Staff | A second member of Venue Staff, for two people deciding at once (SCRUM-53) |
[email protected] | Technical Support | Owns the seeded equipment reservations |
[email protected] | Attendee | Registered for several events |
[email protected] | Event Organiser | Owns one event, to prove another organiser is refused (SCRUM-68) |
[email protected] | Event Coordinator | The "previous" coordinator in the reassignment audit entry (SCRUM-21) |
[email protected] | Attendee | Needed to fill an event (SCRUM-74) |
[email protected] | Attendee | Has one withdrawn registration (SCRUM-77) |
[email protected] | Attendee | Deliberately unregistered, so free to take the last place |
[email protected] | Safety Officer | Reviews operational safety checks (SCRUM-166) |
[email protected] | Event Coordinator Lead | Assigns new requests from the Unassigned Queue (SCRUM-165) and reassigns events from All Events (SCRUM-21) |
[email protected] | Event Coordinator Lead | A second Lead, for two Leads assigning at once (SCRUM-165) |
[email protected] | Safety Officer | A second Safety Officer, for two people recording at once (SCRUM-166) |
[email protected] | Venue Staff, Technical Support, Event Coordinator and Event Organiser | One account with several roles (SCRUM-121) |
Every scenario exists so a specific acceptance criterion can be demonstrated, not just described. If you add seed data, say in a comment which story needs it.
Events: one in each of the nine statuses (SCRUM-23), plus:
| Event | What it demonstrates |
|---|---|
evt_full | Expected attendance 3, which is its registration capacity, with three active registrations: full (SCRUM-74) |
evt_last_seat | Expected attendance 3 with two registrations: exactly one place left. The simultaneous-registration test uses it, and attendee4 is free to take it. |
evt_reg_not_open | Registration opens in a week (SCRUM-75) |
evt_reg_closed | Registration closed yesterday (SCRUM-75) |
evt_other_organiser | Owned by organiser2. Loading it as organiser must look exactly like "not found" (SCRUM-68). |
evt_draft | No dates and no attendance, which proves those columns really are optional (SCRUM-15) |
Venues: four. The Executive Boardroom (capacity 14, few facilities) gives the suitability check something to mark not suitable (SCRUM-40). The Grand Auditorium and Exhibition Hall already have approved bookings, so availability and search have a real clash to exclude (SCRUM-36/38). Seminar Room 2.1 has a maintenance period that is not a booking (SCRUM-36/37). Each venue has opening hours per weekday in Singapore time (SCRUM-34): the Auditorium 07:00–23:00 and the Hall 06:00–22:00 every day; Seminar Room 2.1 08:00–20:00 and the Boardroom 09:00–18:00 on weekdays, both closed at weekends.
Equipment: five pooled types. Three of the ten projectors are in for
maintenance and one PA speaker is written off, so the available quantity is
never simply totalQuantity (SCRUM-29/30).
Also seeded: an open clarification request; a pending change request with three changed fields (two major, one not); venue bookings that are approved, pending, rejected and cancelled; an approved and a pending equipment request with a status history; read and unread notifications; and audit entries.
Every role's work (SCRUM-238): each role has something to see and to act on, and every status has a row. These events sit 50 or more days out:
| Signed in as | What's waiting |
|---|---|
Coordinator (coordinator@) | "Ready to Confirm — Alumni Networking Night" (venue, equipment and safety check done); "Flagged — Sustainability Forum" (a flagged booking and reservation to resolve); "Hold Approved — Founders' Breakfast" (a hold to confirm or release); "Cancellation Requested — Spring Concert" (a cancellation to decide) |
Cara Coordinator (coordinator2@) | "Safety Changes — Robotics Showcase": the Safety Officer asked for changes; No equipment needed recorded |
Lead (lead@) | "Overdue — Orientation Volunteers Briefing", unassigned with a past start, plus the other Submitted requests |
Venue Staff (venuestaff@) | two pending requests (oldest first), a held Boardroom whose deadline was moved, an expired hold, and a flagged booking |
Technical Support (techsupport@) | a request in review with a line short of stock and Laptop suggested instead, an approved request ready to reserve ("Ready to Reserve — Robotics Open House"), a flagged reservation, and rejected and cancelled requests |
Safety Officer (safety@) | a check awaiting review ("Safety Review — Engineering Open Day"), with checks that were approved, rejected, sent back for changes and outdated; the Exhibition Hall has a known restriction |
Organiser (organiser@) | a complete draft ready to submit, a discarded draft, a rejection that asks for a new request, a clarification naming the fields to change, and approved and rejected change requests |
Attendee (attendee@, attendee2@) | "Re-planning — Jazz Night", still showing its last confirmed details; a Confirmed event that takes no registrations |
Multi-role (multirole@) | organises "Multi-role Organiser — Lab Tour", so it can't decide that venue request as Venue Staff; coordinates "Multi-role Coordinator — Debate Finals" |
Every notification type is seeded for the person who would receive it, some read, one shown only from tomorrow and one withdrawn. Venue and equipment unavailability has a row for every reason.
To demo reserving equipment (SCRUM-155): sign in as Technical Support and reserve "Ready to Reserve — Robotics Open House" on Equipment. Or start from the beginning: review and approve the pending "Planning — Freshman Orientation" request first. "Approved — Research Symposium" has no equipment request on purpose: SCRUM-27's tests need it to have none.
Dates are relative to today, not hard-coded, so "registration closes next week" stays true all term. Row IDs are fixed and tests use them directly, so don't rename one without updating its callers.
For a scripted walkthrough of every core workflow on this seed, with a
conflict, change or failure in each, see docs/demo.md.
prisma/schema.prisma covers all twenty Release 1 features. Every model and
field names the story that needs it; if you can't find the story for a column,
it should not be there. docs/data-model.md has the
story-to-table map and the reasoning behind the modelling decisions most
likely to come up in the Q&A.
[) ranges, and lib/period.ts states the
rule once for the application. Every availability query must use it.timestamp(3)) and shown in Singapore
time, only through formatDate / formatDateTime in lib/datetime.ts.
Because the columns carry no time zone, range constraints use tsrange,
not tstzrange.These live in the migrations under prisma/migrations/, below the
Domain constraints Prisma cannot express banner and in later migrations.
They make the acceptance criteria hold even when a server action forgets a
check, so don't work around them.
EXCLUDE USING gist constraint
refuses a second approved or held booking whose occupied period (its times
widened by setup and turnaround, SCRUM-159) overlaps an existing one, even
when two approvals commit at the same instant (SCRUM-53, ADR 0010).Event.timezone must be
Asia/Singapore (SCRUM-129).endAt must be after its startAt.Both are counted pools: overlapping rows are legal until their sum exceeds a
limit. Both are enforced with SELECT … FOR UPDATE inside the writing
transaction. Don't remove these locks.
Event row.Equipment rows, in
id order, after the Event row.Release 1 is not load-tested for three years of growth (briefing §8e).
The briefing gives no dataset size or traffic figures, so the team set its
own testable limits instead: the core pages work at 360 px with no
horizontal scroll, and viewing an event, searching venues, opening a venue's
availability, checking equipment availability and registering each respond
within 2 seconds on the seed data. e2e/phone-and-speed.spec.ts checks both
on every pull request; the timings for the sprint review are in
docs/evidence/.
What the design already does for growth:
EXCLUDE constraint, and counted pools (registration
capacity, equipment quantity) are checked under row locks, so more
concurrent users can't break them (see "Rules the database enforces").@@index in
prisma/schema.prisma), and the double-booking constraint is backed by a
GiST index.What would need work first: lists are not paginated. My Event Requests, the all-events list, the booking and equipment review queues and notifications each read every matching row. Paging them is the first change to make once any of them reaches a few thousand rows.
| Command | What it does |
|---|---|
npm run dev | Start the dev server |
npm run verify | Run before every push: typecheck, lint and unit tests, the checks CI fails on most |
npm run build / npm run start | Production build / serve it |
npm run typecheck | tsc --noEmit |
npm run lint | ESLint (Next and Prettier config) |
npm run format / npm run format:check | Prettier: write / check only |
npm test | All Vitest tests, unit and integration |
npm run test:unit | Unit tests only (database mocked) |
npm run test:integration | Integration tests against a real Postgres: local database only |
npm run test:coverage | All Vitest tests with the 100% coverage check that CI runs: local database only |
npm run test:e2e | Playwright: builds and serves the app, then runs the specs: local database only |
npm run db:deploy | Apply pending migrations; the only migration command for the shared database |
npm run db:seed | Re-run the idempotent seed on the shared database: deletes nothing, but resets seeded rows to their seed values |
npm run db:migrate | Create and apply a new migration: local database only |
npm run db:reset | Drop, migrate and seed: local Docker only |
npm run db:generate | Regenerate the Prisma client |
"Local database only" means the terminal points at Docker first: see Local database (Docker). Never run these bare:
.envpoints at the shared database. Without a local database the integration tests are skipped, andtest:coveragefails on files only they cover.Playwright also needs a browser the first time (
npx playwright install chromium).
main. Fix forward
with a new one. The graders rebuild the database from scratch, and
rewritten history is how a team ends up with one nobody can rebuild.prisma db push. It changes the schema without a migration
file, so your change reaches nobody else's database and production drifts.main applies a migration to the
shared database before the new code is live (deploy.yml), while the
previous deployment is still serving, and it stays applied if the build
then fails. So add tables, nullable columns or columns with a default, and
constraints existing rows already meet. Dropping or renaming a column the
running code reads, or changing its type, takes two pull requests: first
stop the code using it, then remove it.npx prisma migrate resolve --applied <name> (or --rolled-back <name>)
against the shared database, and re-run the deploy from the Actions tab.schema.prisma change at standup before you make it. Five
people edit that one file, and it is this repo's most common merge conflict.prisma migrate dev reports drift mentioning the partial or GiST
indexes, that is expected: Prisma can't model partial WHERE indexes or
EXCLUDE constraints, so it ignores them. Don't "fix" it by deleting them.Routes are grouped by domain, not by role. A route several roles use is one folder whose page switches on the user's role (ADR 0001's addendum). Each domain folder maps to one backlog epic.
.env.example Every variable the app reads
docker-compose.yml Local Postgres: offline fallback and integration tests
proxy.ts Auth gate for every protected route (was middleware.ts)
auth.ts, auth.config.ts Auth.js set-up (JWT sessions, ADR 0002)
prisma/
schema.prisma The full Release 1 data model
migrations/ Ordered, never rewritten; the constraints live here
seed.ts Idempotent demo data
app/
(auth)/login/ Sign-in page
(app)/ Everything behind sign-in (protected by proxy.ts)
layout.tsx Shell: header, role-based nav, user menu
page.tsx Sends each role to its landing page
events/ SCRUM-6 event requests to confirmation; the reference feature
venues/ SCRUM-7 venue catalogue, search and availability calendar
bookings/ SCRUM-7 booking requests and Venue Staff decisions
equipment-requests/ SCRUM-10 Coordinator requests, Technical Support review
equipment/ SCRUM-10 availability check and reserving approved requests
registrations/ SCRUM-11 an attendee's registrations
notifications/ SCRUM-8 each user's notification list (SCRUM-48)
lib/
auth/can.ts Authorisation: roles and relationships, in one place (ADR 0004)
auth/guard.ts requireSession(), used by every page
schemas/ Zod schemas shared by forms and actions
equipment/ Equipment availability and request rules
period.ts The one overlap rule for every period
datetime.ts The only place dates are formatted (Asia/Singapore)
db.ts, db-errors.ts Shared Prisma client; recognising Postgres refusals
components/ui/ shadcn/ui primitives
tests/
unit/ Vitest with the database mocked
integration/ Vitest against a real Postgres: locks, transactions, races
e2e/ Playwright specs, one or more per journey
docs/
product-context.md The product in one page: roles, features, scope, lifecycle
backlog/ Every story's acceptance criteria, generated from Jira
testing/ Test case specifications, one file per story
data-model.md What each table is for and which story needs it
adr/ Architecture Decision Records, with an index
scrum/ Sprint records, estimation and the Definition of Done
evidence/ Screenshots and CI logs captured for sprint reviews
.github/
workflows/ CI, the GLM review, its memory, and deploys
ai-review/ The GLM reviewer's instructions and memory
docs/backlog/ is generated from Jira. Jira is the source of truth, so
re-sync rather than editing those files (see docs/backlog/README.md).
main changes (ADR 0009); there are no preview deploys.DATABASE_URL and DIRECT_URL to the Supabase session
pooler: port 5432, user postgres.<project-ref>, host
aws-0-<region>.pooler.supabase.com. The two "obvious" alternatives fail:
db.<ref>.supabase.co is IPv6-only, so on an
IPv4-only network (most homes and campus Wi-Fi) it times out silently;6543, ?pgbouncer=true) breaks the
prepared statements the pg driver adapter relies on.DATABASE_URL, DIRECT_URL and
AUTH_SECRET. Paste them without quotes. The quotes in .env.example
are dotenv syntax, and Vercel stores them literally.AUTH_URL in production: the app reads the host from the request.
Don't set AUTH_TRUST_HOST either: it is trustHost: true in
auth.config.ts, so it can't be forgotten or mis-quoted.prisma migrate deploy against the shared database before it builds (deploy.yml), so the
database is always on the schema of the code on main; if a migration
fails, nothing is deployed. To apply one by hand, use npm run db:deploy,
never db:reset.CREATE EXTENSION btree_gist, so the double-booking
constraint deploys unchanged.Don't use Supabase Row Level Security. Prisma connects with a privileged role that bypasses it, so it would only give a false sense of protection. Authorisation lives in
lib/auth/can.ts(ADR 0004).