A community-and-events platform for student & professional guilds. Communities host events, members attend with verified check-in/check-out, earn verifiable certificates (QR + serial), build reputation ("Guild Score") and AI-assisted CVs — while organizers monetize through event sponsorships and premium customization.
npm workspaces monorepo:
| Workspace | Stack | Purpose |
|---|---|---|
backend/ |
Express 4 · Mongoose 8 · TypeScript · WebSockets (ws) |
REST API, realtime, schedulers, payments, email |
frontend/ |
Next.js 14 (App Router) · React 18 · Tailwind CSS | Web app (app/), shared UI in components/guildos/ |
mobile/ |
Expo / React Native | Mobile app (early stub) |
docs/ |
Markdown | PRDs per feature, BACKLOG.md, CHANGELOG.md |
- Node.js 20+
- MongoDB running locally (default
mongodb://127.0.0.1:27017/guildos) or a connection string - (Optional) Paystack/Flutterwave, SMTP, OpenAI, Cloudflare R2 credentials — features degrade gracefully without them
# from the repo root
npm install
# copy env template and fill in values
# backend/.env (see table below)
# run frontend + backend + mobile together
npm run dev
# or individually
npm run dev:backend # API on http://localhost:3001
npm run dev:frontend # web on http://localhost:3000Defined in backend/src/config.ts. Everything is optional in dev unless marked required.
| Variable | Default | Notes |
|---|---|---|
PORT |
3001 |
API port |
MONGODB_URI |
mongodb://127.0.0.1:27017/guildos |
Required in production |
JWT_SECRET |
dev-secret-change-me |
Change in production |
CORS_ORIGIN |
http://localhost:3000 |
Frontend origin |
FRONTEND_URL |
http://localhost:3000 |
Used in emails / redirects |
COOKIE_DOMAIN |
– | Set for cross-subdomain auth in prod |
ADMIN_EMAIL / ADMIN_PASSWORD / ADMIN_NAME |
– | Seeds the platform admin account |
| Variable | Notes |
|---|---|
SMTP_HOST / SMTP_PORT / SMTP_USER / SMTP_PASS |
Nodemailer transport (e.g. Gmail) |
EMAIL_FROM |
Sender, default GuildOS <no-reply@guildos.local> |
One gateway is active at a time — toggled by the admin at /dashboard/admin/communities.
| Variable | Notes |
|---|---|
PAYSTACK_SECRET_KEY / PAYSTACK_PUBLIC_KEY |
Paystack; webhook at POST /api/payments/paystack/webhook |
FLUTTERWAVE_SECRET_KEY / FLUTTERWAVE_PUBLIC_KEY / FLUTTERWAVE_SECRET_HASH |
Flutterwave; webhook at POST /api/payments/flutterwave/webhook |
Payments stay disabled (paymentsEnabled=false) until the active gateway has a secret key set.
All five must be set, otherwise uploads fall back to local backend/uploads/:
R2_ACCOUNT_ID, R2_ACCESS_KEY_ID, R2_SECRET_ACCESS_KEY, R2_BUCKET, R2_PUBLIC_BASE_URL
Set a CORS policy on the R2 bucket allowing the frontend origin — the certificate canvas draws logos/signatures cross-origin.
| Variable | Notes |
|---|---|
OPENAI_API_KEY / OPENAI_MODEL |
Assistant, CV builder, certificate wording (template fallback without key) |
GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRET / GOOGLE_REDIRECT_URI |
Google OAuth login |
OPPORTUNITY_SYNC_ENABLED |
true to enable opportunity ingestion |
ADZUNA_APP_ID / ADZUNA_APP_KEY / ADZUNA_COUNTRY |
Adzuna jobs provider |
JOOBLE_API_KEY / JOOBLE_KEYWORDS / JOOBLE_LOCATION |
Jooble jobs provider |
OPPORTUNITY_RSS_FEEDS |
Comma-separated RSS feed URLs |
From the repo root:
| Command | What it does |
|---|---|
npm run dev |
frontend + backend + mobile concurrently |
npm run build:all |
Build all workspaces |
npm test |
Backend Vitest suite (unit tests: fee math, password hashing, JWT) |
Backend one-off scripts (run with tsx, e.g. npx tsx backend/smoke-test.ts): smoke-test.ts, seed-demo-events.ts, seed-cert.ts, verify-community.ts, cleanup-live.ts.
- API — feature-based route modules in backend/src/routes with business logic in backend/src/services; Mongoose models in backend/src/models.
- Auth — JWT access/refresh cookies, email verification, password reset, Google OAuth; middleware in backend/src/middleware/auth.ts.
- Realtime — WebSocket layer in backend/src/realtime.ts for notifications and messaging.
- Schedulers — in-process intervals (event reminders/finalization, premium expiry, payment reconciliation, opportunity sync) started from backend/src/server.ts. Single-instance assumption.
- Certificates — issued on verified attendance, snapshotted onto the
Certificatemodel, rendered client-side on canvas via frontend/components/guildos/certificate-canvas.ts (12 designs, themes, signatures, sponsor strips), verified publicly at/certificates/[serial]. - Payments — gateway abstraction in backend/src/services/payment-gateway.service.ts; amount/currency verified before entitlements are granted; idempotent verification + scheduled reconciliation of stuck payments.
- Uploads — multer memory storage → R2 (or local disk); DB always stores relative
/uploads/<key>paths, resolved at request time.
npm test # run once
npm run test:watch -w backendTests live next to sources as *.test.ts (excluded from the production build). Current coverage is unit-level only; integration tests (certificate/attendance chain, payment gating) are the next planned layer — see docs/BACKLOG.md.
- Feature PRDs: docs/ (one per feature, e.g. certificate generation, attendance verification, guild score)
- Roadmap: docs/BACKLOG.md
- Change history: docs/CHANGELOG.md