Skip to content

About

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

532 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Bananasplit

The all-in-one workspace for student clubs (and the teams that grow out of them): tasks, availability polls and RSVPs, notes and files, databases, the club budget, and the org chart, for every member, in one multi-tenant app.

The marketing site (/), sign-in, sign-up, onboarding and checkout follow the brand design (src/app/brand.css, src/components/brand/); each club's workspace takes its own theme, with the Bananasplit preset as the default. See docs/features/themes.md.

Stack

Next.js (App Router) + React + TypeScript, Postgres via Prisma, Auth.js (Google OAuth + email/ password), Tailwind CSS + shadcn/ui. See the project spec for the full rationale.

Sign-in supports both Google OAuth and email/password (bcrypt-hashed, /sign-up to register). Email/password is a deliberate addition beyond the original spec, which scoped v1 to Google-only. "Continue with Google" (on /sign-in, /sign-up and /invite/[token]) appears only when AUTH_GOOGLE_ID and AUTH_GOOGLE_SECRET are both set (src/lib/auth/google-sign-in.ts); without them the pages offer email and password only. Google Calendar sync (Settings > Integrations) is a separate OAuth client.

Local setup

  1. Install dependencies

    pnpm install
  2. Configure environment variables

    cp .env.example .env

    Fill in DATABASE_URL (a local Postgres instance; production runs on Supabase, see RUNBOOK.md) and AUTH_SECRET (npx auth secret). The app also connects at runtime as three non-owner, row-level-security-scoped roles (app_user / app_service / app_auth, see docs/ARCHITECTURE.md) instead of the owner; locally, set APP_DB_PASSWORD, SERVICE_DB_PASSWORD and AUTH_DB_PASSWORD to test — pnpm db:local-roles (next step) gives the roles that same password. Generate SECRETS_KEK_V1 and SECRETS_FINGERPRINT_KEY too (base64 of 32 random bytes each: node -e "console.log(require('crypto').randomBytes(32).toString('base64'))"), which the secrets-at-rest keyring (integrations settings, /api/health) needs. AUTH_GOOGLE_ID / AUTH_GOOGLE_SECRET need a real Google Cloud OAuth client (spec section 11, item 1) — request only openid email profile, with http://localhost:3000 as an authorized JavaScript origin and http://localhost:3000/api/auth/callback/google as a redirect URI. Leave both empty unless you have one: "Continue with Google" only appears when both are set, so placeholder values would show a button that fails. You don't need Google for local development: every seeded user (see below) signs in with email/password. See .env.example for what each variable is for.

  3. Set up the database (from Phase 0.3 onward)

    pnpm prisma migrate deploy
    pnpm db:local-roles
    pnpm db:seed

    migrate deploy applies the committed migrations without prompting. (pnpm db:migrate, i.e. prisma migrate dev, is for authoring a new migration when you change prisma/schema.prisma — see CONTRIBUTING.md — and can hang on an interactive prompt if run here instead.) db:local-roles gives the app_user / app_service / app_auth roles (created NOLOGIN by the migrations) the local password set above; see RUNBOOK.md for how production provisions them instead. Every seeded user (e.g. alice@example.edu, see prisma/seed.ts for the full roster and roles) can sign in at /sign-in with password password123.

  4. Run the dev server

    pnpm dev

    Open http://localhost:3000.

Scripts

Command Purpose
pnpm dev Start the dev server
pnpm build Production build
pnpm start Start a production build (after pnpm build)
pnpm lint ESLint
pnpm typecheck next typegen && tsc --noEmit
pnpm format Format with Prettier
pnpm format:check Check formatting without writing
pnpm test Unit/integration tests (Vitest)
pnpm test:rls Row-level-security regression + attack suite (spins up its own throwaway Postgres DB)
pnpm test:e2e End-to-end browser tests (Playwright)
pnpm db:migrate prisma migrate dev — author/apply a migration while changing prisma/schema.prisma
pnpm db:seed Seed the local database (prisma/seed.ts)
pnpm db:local-roles Give the RLS runtime roles a local login password
pnpm db:studio Prisma Studio
pnpm jobs:drain Run due background jobs locally (mail, reminders, syncs, maintenance)
pnpm secrets:rotate-kek Rewrap stored secrets under a new key-encryption key (see RUNBOOK.md)

Documentation

  • CONTRIBUTING.md — conventions for making a change.
  • docs/ARCHITECTURE.md — the multi-tenant model and how authorization is enforced.
  • docs/features/ — one doc per feature area (calendar, tasks, org chart, databases, reports, settings, themes, onboarding, profiles, search, platform services).
  • docs/EBOARD-HANDBOOK.md — for the club's e-board, not developers: treasurer handoff, ongoing habits, continuity.
  • RUNBOOK.md — deploying for the first time and restoring from backup.

Project status

Following the phased build-out in the project spec. Phases 0–6 (foundation through hardening: notifications, an authorization audit, accessibility fixes, performance work, E2E tests, and deployment/docs prep) are done. Phase 7's Google Calendar sync (src/server/google-calendar/), the public events feed (src/server/public-events/, /api/public/[orgSlug]/events), and optional notices to event attendees are built too — see docs/features/calendar.md. Real-time collaborative editing is not: per the spec's own sequencing it stays intentionally deferred until v1 has run with a real e-board for a month.

About

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages