Skip to content

Repository files navigation

Tulis Backend API

A Go-based REST API backend for Tulis, a content management system built with Fiber framework.

Tech Stack

  • Framework: Go Fiber v2
  • ORM: GORM (MySQL & SQLite support)
  • Authentication: JWT with golang-jwt/jwt
  • Storage: Local filesystem or Cloudflare R2 (S3-compatible)
  • Documentation: Swagger/OpenAPI via swaggo
  • Logging: Logrus
  • Container: Docker & Docker Compose

Project Structure

backend/
├── cmd/api/              # Application entry point
│   └── main.go
├── config/               # Configuration loading
├── domain/               # Domain-driven architecture
│   ├── importer/         # WordPress WXR import functionality
│   ├── media/            # Media management
│   ├── plugin/           # Plugin system
│   ├── post/             # Posts, taxonomies, post types
│   ├── user/             # User authentication & management
│   └── workspace/        # Multi-tenant workspace management
├── middleware/            # Fiber middleware (auth, tenant scoping)
├── routes/               # Route registration
├── storage/              # Storage abstraction (local/R2)
├── utils/                # Utilities (JWT service)
├── docs/                 # Swagger documentation
├── docker-compose.yml    # Docker services
├── Dockerfile
└── .env.example          # Environment template

Getting Started

Prerequisites

  • Go 1.21+
  • MySQL 8.0+ or SQLite
  • Docker & Docker Compose (optional)

Local Development

  1. Clone and install dependencies
cd tulis-go
go mod download
  1. Setup environment variables
cp .env.example .env
# Edit .env with your database credentials and secrets
  1. Configure database

Edit .env with your database settings:

APP_ENV=development
APP_PORT=8080
DB_HOST=127.0.0.1
DB_PORT=3306
DB_USER=root
DB_PASSWORD=your_password
DB_NAME=tulis_app
JWT_SECRET=your-secret-key
  1. Run with live reload
# Using Air for live reload
air

Or directly:

go run cmd/api/main.go
  1. Access Swagger documentation

Open http://localhost:8080/swagger after starting the server.

Docker Development

# Build and run all services
docker-compose up --build

# Run only the API container
docker-compose up --build api

The API will be available at http://localhost:8080.

Environment Variables

Variable Description Default
APP_ENV Environment mode development
APP_PORT Server port 8080
DB_HOST Database host 127.0.0.1
DB_PORT Database port 3306
DB_USER Database user root
DB_PASSWORD Database password -
DB_NAME Database name tulis_app
JWT_SECRET JWT signing secret super-secret-key
JWT_EXPIRY_HOURS Token expiry in hours 24
WORKSPACE_RESTRICTED Restrict workspace creation false
ALLOW_REGISTRATION Allow new user signup true
R2_ACCOUNT_ID Cloudflare R2 account ID -
R2_ACCESS_KEY_ID R2 access key -
R2_SECRET_ACCESS_KEY R2 secret key -
R2_BUCKET_NAME R2 bucket name tulis-media
R2_PUBLIC_URL R2 public URL -

OAuth Configuration

To enable login with Google, GitHub, or GitLab, you need to obtain OAuth credentials from each provider.

Variable Description
GOOGLE_CLIENT_ID Google OAuth 2.0 Client ID
GOOGLE_CLIENT_SECRET Google OAuth 2.0 Client Secret
GOOGLE_REDIRECT_URL Google OAuth callback URL
GITHUB_CLIENT_ID GitHub OAuth App Client ID
GITHUB_CLIENT_SECRET GitHub OAuth App Client Secret
GITHUB_REDIRECT_URL GitHub OAuth callback URL
GITLAB_CLIENT_ID GitLab OAuth Application Client ID
GITLAB_CLIENT_SECRET GitLab OAuth Application Client Secret
GITLAB_REDIRECT_URL GitLab OAuth callback URL

Google OAuth Setup

  1. Go to Google Cloud Console
  2. Create a new project or select existing one
  3. Navigate to APIs & Services > Credentials
  4. Click Create Credentials > OAuth client ID
  5. Select Web application as application type
  6. Add authorized redirect URI: http://localhost:8080/api/auth/google/callback (for development)
  7. Copy Client ID and Client Secret
  8. In Google Cloud Console, enable Google+ API if not already enabled:
    • Go to APIs & Services > Library
    • Search for "Google+ API" and enable it

GitHub OAuth App Setup

  1. Go to GitHub Developer Settings
  2. Click OAuth Apps > New OAuth App
  3. Fill in application details:
    • Application name: Tulis CMS (or your choice)
    • Homepage URL: http://localhost:3000
    • Authorization callback URL: http://localhost:8080/api/auth/github/callback
  4. Click Register application
  5. Copy Client ID and generate a new Client Secret

GitLab OAuth Application Setup

  1. Go to GitLab > Preferences > Applications
  2. Click Add new application
  3. Fill in application details:
    • Name: Tulis CMS (or your choice)
    • Redirect URI: http://localhost:8080/api/auth/gitlab/callback
    • Scopes: Select read_user scope
  4. Click Save application
  5. Copy Application ID (as Client ID) and Secret

Production Redirect URLs

For production, update the redirect URLs to match your domain:

Provider Production Redirect URL
Google https://api.yourdomain.com/api/auth/google/callback
GitHub https://api.yourdomain.com/api/auth/github/callback
GitLab https://api.yourdomain.com/api/auth/gitlab/callback

API Structure

Public Endpoints (Rate Limited)

GET  /api/v1/public/posts           # List published posts
GET  /api/v1/public/posts/:slug     # Get post by slug
GET  /api/v1/public/media/:id       # Get media by ID

Authentication Endpoints

POST /api/user/register              # User registration
POST /api/user/login                 # User login
GET  /api/user/me                    # Get current user

# OAuth Authentication
GET  /api/auth/google                # Redirect to Google OAuth
GET  /api/auth/google/callback        # Google OAuth callback
GET  /api/auth/github                # Redirect to GitHub OAuth
GET  /api/auth/github/callback       # GitHub OAuth callback
GET  /api/auth/gitlab                # Redirect to GitLab OAuth
GET  /api/auth/gitlab/callback       # GitLab OAuth callback

Protected Endpoints (Require JWT)

# Workspace
GET    /api/workspaces                # List user's workspaces
POST   /api/workspaces                # Create workspace
GET    /api/workspaces/:id            # Get workspace
PUT    /api/workspaces/:id            # Update workspace
DELETE /api/workspaces/:id            # Delete workspace
POST   /api/workspaces/:id/members    # Add member
DELETE /api/workspaces/:id/members/:userId  # Remove member

# Posts
GET    /api/posts                     # List posts (tenant-scoped)
POST   /api/posts                     # Create post
GET    /api/posts/:id                 # Get post
PUT    /api/posts/:id                 # Update post
DELETE /api/posts/:id                 # Delete post
POST   /api/posts/:id/revisions       # Create revision

# Taxonomies
GET    /api/taxonomies                # List taxonomies
POST   /api/taxonomies                # Create taxonomy
PUT    /api/taxonomies/:id            # Update taxonomy
DELETE /api/taxonomies/:id            # Delete taxonomy

# Media
GET    /api/media                     # List media
POST   /api/media/upload              # Upload media
DELETE /api/media/:id                 # Delete media

# Plugins
GET    /api/plugins                   # List plugins
POST   /api/plugins                   # Install plugin
PUT    /api/plugins/:id               # Update plugin
DELETE /api/plugins/:id               # Uninstall plugin

# Importer
POST   /api/import/wxr                # Import WordPress WXR
GET    /api/import/logs               # Import logs

Headers

Protected endpoints require:

Authorization: Bearer <jwt_token>
X-Workspace-ID: <workspace_id>

Features

Multi-tenant Workspaces

  • Each workspace operates as an independent tenant
  • Members can be assigned roles within workspace
  • All data is scoped to workspace context

Post Management

  • Custom post types
  • Taxonomy support (categories, tags)
  • Post revisions for content history
  • Markdown support

Media Library

  • File upload with automatic optimization
  • Cloudflare R2 or local storage
  • Image processing support

WordPress Importer

  • Import posts from WordPress WXR format
  • Preserves media attachments
  • Migration tool for content transfer

Plugin System

  • Extensible workspace plugins
  • Enable/disable plugins per workspace

OAuth Authentication

  • Login/Register with Google, GitHub, or GitLab
  • Automatic account linking by email
  • Workspace auto-creation for new users (when not restricted)
  • Email automatically verified for OAuth users

Testing

# Run all tests
go test ./...

# Run tests with coverage
go test -cover ./...

# Run specific domain tests
go test ./domain/post/...

Development

Generate Swagger Documentation

swag init -g cmd/api/main.go -o docs

Code Formatting

go fmt ./...
go mod tidy

License

Private project. All rights reserved.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages