feat: add server foundation (config, database, auth, main)
- config: Load from env vars (SERVER_PORT, DATABASE_URL, JWT_SECRET, CAS_DIR, etc.) - database: pgx/v5 connection pool, models (User, YggdrasilSession, Modpack, GlobalFile, LauncherRelease) - auth: Yggdrasil endpoints (authenticate, refresh, validate) with SHA-256 password hashing, token rotation - main: graceful shutdown, HTTP server on configured port - go.mod: module gitea.mrixs.me/Mrixs/MrixsCraft-server, pgx/v5 dependency Co-Authored-By: OWL <noreply@anthropic.com>
This commit is contained in:
@@ -1,2 +1,87 @@
|
||||
// package database manages PostgreSQL connections, migrations, and data models.
|
||||
// package database manages PostgreSQL connections and data models.
|
||||
package database
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/jackc/pgx/v5/pgxpool"
|
||||
)
|
||||
|
||||
// DB wraps pgxpool.Pool with application-specific helpers.
|
||||
type DB struct {
|
||||
pool *pgxpool.Pool
|
||||
}
|
||||
|
||||
// Open creates a new database connection pool.
|
||||
func Open(ctx context.Context, databaseURL string) (*DB, error) {
|
||||
pool, err := pgxpool.New(ctx, databaseURL)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("connecting to database: %w", err)
|
||||
}
|
||||
if err := pool.Ping(ctx); err != nil {
|
||||
pool.Close()
|
||||
return nil, fmt.Errorf("pinging database: %w", err)
|
||||
}
|
||||
return &DB{pool: pool}, nil
|
||||
}
|
||||
|
||||
// Close shuts down the connection pool.
|
||||
func (db *DB) Close() {
|
||||
db.pool.Close()
|
||||
}
|
||||
|
||||
// Pool returns the underlying pool for direct queries.
|
||||
func (db *DB) Pool() *pgxpool.Pool {
|
||||
return db.pool
|
||||
}
|
||||
|
||||
// ── Models ─────────────────────────────────────────────────────
|
||||
|
||||
// User represents a registered player.
|
||||
type User struct {
|
||||
ID int `db:"id"`
|
||||
Username string `db:"username"`
|
||||
Email string `db:"email"`
|
||||
PasswordHash string `db:"password_hash"`
|
||||
UUID string `db:"uuid"`
|
||||
Role string `db:"role"`
|
||||
}
|
||||
|
||||
// YggdrasilSession represents an active authentication session.
|
||||
type YggdrasilSession struct {
|
||||
ClientToken string `db:"client_token"`
|
||||
AccessToken string `db:"access_token"`
|
||||
UserID int `db:"user_id"`
|
||||
ExpiresAt string `db:"expires_at"`
|
||||
}
|
||||
|
||||
// Modpack represents a game server / modpack configuration.
|
||||
type Modpack struct {
|
||||
ID int `db:"id"`
|
||||
Slug string `db:"slug"`
|
||||
Name string `db:"name"`
|
||||
MinecraftVersion string `db:"minecraft_version"`
|
||||
JavaVersion int `db:"java_version"`
|
||||
ServerIP string `db:"server_ip"`
|
||||
IsActive bool `db:"is_active"`
|
||||
}
|
||||
|
||||
// GlobalFile is a CAS entry.
|
||||
type GlobalFile struct {
|
||||
SHA1 string `db:"sha1"`
|
||||
Size int64 `db:"size_bytes"`
|
||||
FileName string `db:"file_name"`
|
||||
}
|
||||
|
||||
// LauncherRelease tracks published launcher binaries.
|
||||
type LauncherRelease struct {
|
||||
ID int `db:"id"`
|
||||
Version string `db:"version"`
|
||||
OS string `db:"os"`
|
||||
Arch string `db:"arch"`
|
||||
SHA256 string `db:"sha256"`
|
||||
FilePath string `db:"file_path"`
|
||||
IsActive bool `db:"is_active"`
|
||||
IsMandatory bool `db:"is_mandatory"`
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user