Skip to content

Repository files navigation

Capy

Capy is an experimental real-time community platform built with Go and React. It provides a REST API, JWT authentication, WebSocket events for live updates, text and voice channels, PostgreSQL persistence, and LiveKit integration for voice rooms.

Note

Capy is under active development and is not production-ready. Defaults are optimized for local development.

Features

  • JWT authentication with access and refresh tokens
  • Base-oriented communities with joined-base membership
  • Text and voice channel support
  • Real-time WebSocket event pipeline
  • Message history retrieval for text channels
  • LiveKit voice room token generation and webhook handling
  • PostgreSQL storage with GORM auto-migrations
  • Swagger/OpenAPI documentation
  • React + TypeScript web client scaffold
  • Docker setup for the API, PostgreSQL, and PgAdmin

Architecture

capy
|-- cmd/                 # API server and helper CLI entry points
|-- internal/api/        # Gin handlers, middleware, requests, responses
|-- internal/config/     # Environment-based application config
|-- internal/domain/     # Models and repository interfaces
|-- internal/service/    # Auth, base, channel, message, voice services
|-- internal/websocket/  # WebSocket manager, clients, event handlers
|-- pkg/database/        # PostgreSQL connection and migrations
|-- swagger_docs/        # Generated Swagger/OpenAPI files
`-- web/                 # React + Vite frontend

The API is served from cmd/api/main.go with a /api/v1 base path. The web app currently targets http://localhost:9091/api/v1.

Prerequisites

  • Go 1.24+
  • Node.js and npm
  • PostgreSQL 17+ or Docker
  • LiveKit credentials for voice-channel flows
  • swag CLI if you want to regenerate Swagger docs locally

Install swag:

go install github.com/swaggo/swag/cmd/swag@latest

Quickstart

1. Configure environment

Create or update .env in the project root:

DB_HOST=127.0.0.1
DB_PORT=5432
DB_USER=capybara_user
DB_PASSWORD=capybara_password
DB_NAME=capybara_db

SERVER_PORT=9091
CAPYBARA_SERVER_PORT=9091
ENV=development

JWT_SECRET=change_me
REFRESH_SECRET=change_me_too

LIVEKIT_API_KEY=devkey
LIVEKIT_API_SECRET=secret
LIVEKIT_URL=http://localhost:7880

PGADMIN_EMAIL=admin@example.com
PGADMIN_PASSWORD=admin
PGADMIN_PORT=5050

Important

The Go config reads ENV, not ENVIRONMENT. Use strong JWT_SECRET and REFRESH_SECRET values outside local development.

2. Start PostgreSQL

With Docker Compose:

docker compose up -d postgres pgadmin

Or use your own PostgreSQL instance and match the .env values above.

3. Run the API

go mod download
make run

The API starts on:

  • Health check: http://localhost:9091/api/health
  • Swagger UI: http://localhost:9091/api/v1/swagger/index.html
  • API base URL: http://localhost:9091/api/v1

4. Run the web client

cd web
npm install
npm run dev

Vite will print the local web URL, usually http://localhost:5173.

Docker

Run the API and database services:

docker compose up -d postgres pgadmin capybara-api

Warning

docker-compose.yml also defines a capybara-web service, but web/Dockerfile is not present in this repository. Running the full Compose stack without adding that Dockerfile will fail.

API Overview

Public endpoints:

Method Path Description
GET /api/health Health check
POST /api/v1/auth/register Register and receive tokens
POST /api/v1/auth/login Login with email/username and password
POST /api/v1/auth/refresh Refresh token pair
POST /api/v1/webhooks/livekit LiveKit webhook receiver

Authenticated endpoints:

Method Path Description
GET /api/v1/auth/check-session Validate current access token
GET /api/v1/profile Get authenticated profile
GET /api/v1/base List available bases
GET /api/v1/base/joined List bases joined by the current user
POST /api/v1/base/join Join a base
GET /api/v1/base/joined-voice-channel Get the current joined voice channel
GET /api/v1/base/{baseID}/channels List channels in a base
POST /api/v1/base/{baseID}/channels Create a text or voice channel
GET /api/v1/base/{baseID}/voice-channel-users List connected voice users
GET /api/v1/base/{baseID}/channels/{channelID}/messages List channel messages
POST /api/v1/base/{baseID}/channels/{channelID}/join-voice Create a LiveKit join token
POST /api/v1/base/{baseID}/channels/{channelID}/leave-voice Leave the current voice channel

Use Authorization: Bearer <access_token> for authenticated routes.

WebSocket

Connect with an access token query parameter:

ws://localhost:9091/api/v1/ws?token=<access_token>

Events use the shared shape:

{
  "type": "NEW_TEXT_MESSAGE",
  "timestamp": "2026-06-16T00:00:00Z",
  "data": {}
}

The domain model defines events for text/image/voice messages, channel changes, voice state, user presence, typing, and errors.

Development

Common API commands:

make run              # generate Swagger docs and run the API
make build            # generate Swagger docs and build bin/api
make test             # run Go tests
make swag             # regenerate Swagger docs
make clean            # remove built binaries

Create development data:

make create-user email="user@example.com" username="user1" password="password123"
make create-base username="user1" name="Base1" desc="My first base"

Frontend commands:

cd web
npm run dev
npm run build
npm run lint
npm run preview

Notes

  • Database tables are migrated automatically on API startup.
  • Channel types are CHANNEL_TYPE_TEXT and CHANNEL_TYPE_VOICE.
  • Swagger docs are generated into swagger_docs/; older generated files also exist under cmd/docs/.
  • The root package.json only contains frontend-related dependencies; the runnable web scripts live in web/package.json.

About

Capy is an experimental real-time community platform built with Go and React.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages