Skip to content

docs

import "github.com/off-by-2/sal/docs"

Package docs Code generated by swaggo/swag. DO NOT EDIT

Index

Variables

SwaggerInfo holds exported Swagger Info so clients can modify it

var SwaggerInfo = &swag.Spec{
    Version:          "1.0",
    Host:             "localhost:8000",
    BasePath:         "/api/v1",
    Schemes:          []string{},
    Title:            "Sal API",
    Description:      "The high-performance backend for Salvia (Sal).",
    InfoInstanceName: "swagger",
    SwaggerTemplate:  docTemplate,
    LeftDelim:        "{{",
    RightDelim:       "}}",
}

migrations

import "github.com/off-by-2/sal/migrations"

Package migrations embeds database migration files.

Index

Variables

FS holds the embedded migration SQL files. It is used by goose to run migrations.

var FS embed.FS

api

import "github.com/off-by-2/sal/cmd/api"

Package main serves as the entry point for the Sal API server. It handles dependency injection, route configuration, and graceful shutdown.

@title Sal API @version 1.0 @description The high-performance backend for Salvia (Sal). @termsOfService http://swagger.io/terms/

@contact.name API Support @contact.url http://www.swagger.io/support @contact.email support@salvia.com

@license.name MIT @license.url https://opensource.org/licenses/MIT

@host localhost:8000 @BasePath /api/v1

Package main serves as the entry point for the Sal API server. It handles dependency injection, route configuration, and graceful shutdown.

Index

type Server

Server is the main HTTP server container. It holds references to all shared dependencies required by HTTP handlers.

type Server struct {
    Router *chi.Mux           // Router handles HTTP routing
    DB     *database.Postgres // DB provides access to the database connection pool
    Config *config.Config     // Config holds application configuration
    // contains filtered or unexported fields
}

func NewServer

func NewServer(cfg *config.Config, db *database.Postgres) *Server

NewServer creates and configures a new HTTP server.

func (*Server) Shutdown

func (s *Server) Shutdown(ctx context.Context) error

Shutdown gracefully stops the HTTP server.

func (*Server) Start

func (s *Server) Start() error

Start runs the HTTP server.

migrate

import "github.com/off-by-2/sal/cmd/migrate"

Package main is the entrypoint for the database migration tool. It uses pressly/goose to manage database schema versions.

Index

auth

import "github.com/off-by-2/sal/internal/auth"

Package auth provides authentication primitives.

Index

Constants

AccessTokenDuration is the lifespan of an access token (15 minutes).

const AccessTokenDuration = 15 * time.Minute

RefreshTokenLen is the byte length of the refresh token (32 bytes = 64 hex chars).

const RefreshTokenLen = 32

func CheckPasswordHash

func CheckPasswordHash(password, hash string) error

CheckPasswordHash compares a bcrypt hashed password with a plain text password. Returns nil if the passwords match, or an error if they don't.

func HashPassword

func HashPassword(password string) (string, error)

HashPassword hashes a plain text password using bcrypt with a default cost.

func NewAccessToken

func NewAccessToken(userID, orgID, role, secret string) (string, error)

NewAccessToken creates a signed JWT for the given user context.

func NewRefreshToken

func NewRefreshToken() (string, error)

NewRefreshToken generates a secure random hex string. This matches the format expected by the 'refresh_tokens' table.

type Claims

Claims represents the JWT payload.

type Claims struct {
    UserID string `json:"sub"`
    OrgID  string `json:"org_id,omitempty"`
    Role   string `json:"role,omitempty"`
    jwt.RegisteredClaims
}

func ParseAccessToken

func ParseAccessToken(tokenString, secret string) (*Claims, error)

ParseAccessToken validates the token string and returns the claims.

config

import "github.com/off-by-2/sal/internal/config"

Package config handles environment variable loading and application configuration.

Index

type Config

Config holds all configuration values for the application.

type Config struct {
    DatabaseURL string
    Port        string
    Env         string
    JWTSecret   string
}

func Load

func Load() *Config

Load retrieves configuration from environment variables. It attempts to load from a .env file first, falling back to system environment variables. Default values are provided for development convenience.

database

import "github.com/off-by-2/sal/internal/database"

Package database manages the PostgreSQL connection pool and related utilities.

Index

type Postgres

Postgres holds the connection pool to the database.

type Postgres struct {
    Pool *pgxpool.Pool
}

func New

func New(ctx context.Context, connectionString string) (*Postgres, error)

New creates a new Postgres connection pool with optimized production settings. It parses the connection string, sets connection limits, and verifies the connection with a Ping.

func (*Postgres) Close

func (p *Postgres) Close()

Close ensures the database connection pool allows graceful shutdown. It waits for active queries to finish before closing connections.

func (*Postgres) Health

func (p *Postgres) Health(ctx context.Context) error

Health checks the status of the database connection. It returns nil if the database is reachable, or an error if it is not.

handler

import "github.com/off-by-2/sal/internal/handler"

Package handler provides HTTP handlers for the API.

Index

type AuthHandler

AuthHandler handles authentication requests.

type AuthHandler struct {
    DB        *database.Postgres
    UserRepo  *repository.UserRepository
    OrgRepo   *repository.OrganizationRepository
    StaffRepo *repository.StaffRepository
    JWTSecret string
    Validator *validator.Validate
}

func NewAuthHandler

func NewAuthHandler(db *database.Postgres, userEq *repository.UserRepository, orgEq *repository.OrganizationRepository, staffEq *repository.StaffRepository, jwtSecret string) *AuthHandler

NewAuthHandler creates a new AuthHandler.

func (*AuthHandler) Login

func (h *AuthHandler) Login(w http.ResponseWriter, r *http.Request)

Login authenticates a user and returns tokens. @Summary Login @Description Authenticates user by email/password and returns JWT pairs. @Tags auth @Accept json @Produce json @Param input body LoginInput true "Login Credentials" @Success 200 {object} response.Response{data=map[string]string} "Tokens" @Failure 401 {object} response.Response "Unauthorized" @Router /auth/login [post]

func (*AuthHandler) Register

func (h *AuthHandler) Register(w http.ResponseWriter, r *http.Request)

Register creates a new user, organization, and admin staff entry atomically. @Summary Register a new Admin @Description Creates a new User, Organization, and links them as Admin Staff. @Tags auth @Accept json @Produce json @Param input body RegisterInput true "Registration Config" @Success 201 {object} response.Response{data=map[string]interface{}} "User and Org created" @Failure 400 {object} response.Response "Validation Error" @Failure 500 {object} response.Response "Internal Server Error" @Router /auth/register [post]

type LoginInput

LoginInput defines the payload for login.

type LoginInput struct {
    Email    string `json:"email" validate:"required,email"`
    Password string `json:"password" validate:"required"`
}

type RegisterInput

RegisterInput defines the payload for admin registration.

type RegisterInput struct {
    Email     string `json:"email" validate:"required,email"`
    Password  string `json:"password" validate:"required,min=8"`
    FirstName string `json:"first_name" validate:"required"`
    LastName  string `json:"last_name" validate:"required"`
    OrgName   string `json:"org_name" validate:"required"`
}

repository

import "github.com/off-by-2/sal/internal/repository"

Package repository implements data access for the Salvia application.

Package repository implements data access for the Salvia application.

Index

Variables

var (
    // ErrUserNotFound is returned when a user cannot be found in the database.
    ErrUserNotFound = errors.New("user not found")
    // ErrDuplicateEmail is returned when an email is already taken.
    ErrDuplicateEmail = errors.New("email already exists")
)

type Organization

Organization represents a row in the organizations table.

type Organization struct {
    ID        string    `json:"id"`
    Name      string    `json:"name"`
    Slug      string    `json:"slug"`
    OwnerID   string    `json:"owner_id"`
    CreatedAt time.Time `json:"created_at"`
    UpdatedAt time.Time `json:"updated_at"`
}

type OrganizationRepository

OrganizationRepository handles database operations for organizations.

type OrganizationRepository struct {
    // contains filtered or unexported fields
}

func NewOrganizationRepository

func NewOrganizationRepository(db *database.Postgres) *OrganizationRepository

NewOrganizationRepository creates a new OrganizationRepository.

func (*OrganizationRepository) CreateOrg

func (r *OrganizationRepository) CreateOrg(ctx context.Context, o *Organization) error

CreateOrg inserts a new organization.

type Staff

Staff represents a row in the staff table.

type Staff struct {
    ID             string                 `json:"id"`
    OrganizationID string                 `json:"organization_id"`
    UserID         string                 `json:"user_id"`
    Role           string                 `json:"role"`        // 'admin' or 'staff'
    Permissions    map[string]interface{} `json:"permissions"` // JSONB
    CreatedAt      time.Time              `json:"created_at"`
    UpdatedAt      time.Time              `json:"updated_at"`
}

type StaffRepository

StaffRepository handles database operations for staff.

type StaffRepository struct {
    // contains filtered or unexported fields
}

func NewStaffRepository

func NewStaffRepository(db *database.Postgres) *StaffRepository

NewStaffRepository creates a new StaffRepository.

func (*StaffRepository) CreateStaff

func (r *StaffRepository) CreateStaff(ctx context.Context, s *Staff) error

CreateStaff inserts a new staff member.

type User

User represents a row in the users table.

type User struct {
    ID              string    `json:"id"`
    Email           string    `json:"email"`
    EmailVerified   bool      `json:"email_verified"`
    PasswordHash    string    `json:"-"` // Never return password hash in JSON
    AuthProvider    string    `json:"auth_provider"`
    FirstName       string    `json:"first_name"`
    LastName        string    `json:"last_name"`
    Phone           *string   `json:"phone,omitempty"`
    ProfileImageURL *string   `json:"profile_image_url,omitempty"`
    IsActive        bool      `json:"is_active"`
    CreatedAt       time.Time `json:"created_at"`
    UpdatedAt       time.Time `json:"updated_at"`
}

type UserRepository

UserRepository handles database operations for users.

type UserRepository struct {
    // contains filtered or unexported fields
}

func NewUserRepository

func NewUserRepository(db *database.Postgres) *UserRepository

NewUserRepository creates a new UserRepository.

func (*UserRepository) CreateUser

func (r *UserRepository) CreateUser(ctx context.Context, u *User) error

CreateUser inserts a new user into the database.

func (*UserRepository) GetUserByEmail

func (r *UserRepository) GetUserByEmail(ctx context.Context, email string) (*User, error)

GetUserByEmail retrieves a user by their email address.

response

import "github.com/off-by-2/sal/internal/response"

Package response provides helper functions for sending consistent JSON responses.

Index

func Error

func Error(w http.ResponseWriter, status int, message string)

Error sends a standardized error response.

func JSON

func JSON(w http.ResponseWriter, status int, data interface{})

JSON sends a JSON response with the given status code and data.

func ValidationError

func ValidationError(w http.ResponseWriter, err error)

ValidationError sends a response with detailed validation errors. It parses go-playground/validator errors into a simplified map.

type Response

Response represents the standard JSON envelope for all API responses.

type Response struct {
    Success bool        `json:"success"`         // Success indicates if the request was successful
    Data    interface{} `json:"data,omitempty"`  // Data holds the payload (can be struct, map, or nil)
    Error   interface{} `json:"error,omitempty"` // Error holds error details if Success is false
    Meta    interface{} `json:"meta,omitempty"`  // Meta holds pagination or other metadata
}

Generated by gomarkdoc