mirror of
https://github.com/get-drexa/drive.git
synced 2026-02-03 01:01:17 +00:00
feat: initial backend scaffolding
migrating away from convex Co-authored-by: Ona <no-reply@ona.com>
This commit is contained in:
23
apps/backend/internal/drexa/err.go
Normal file
23
apps/backend/internal/drexa/err.go
Normal file
@@ -0,0 +1,23 @@
|
||||
package drexa
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type ServerConfigError struct {
|
||||
Errors []error
|
||||
}
|
||||
|
||||
func NewServerConfigError(errs ...error) *ServerConfigError {
|
||||
return &ServerConfigError{Errors: errs}
|
||||
}
|
||||
|
||||
func (e *ServerConfigError) Error() string {
|
||||
sb := strings.Builder{}
|
||||
sb.WriteString("invalid server config:\n")
|
||||
for _, err := range e.Errors {
|
||||
sb.WriteString(fmt.Sprintf(" - %s\n", err.Error()))
|
||||
}
|
||||
return sb.String()
|
||||
}
|
||||
84
apps/backend/internal/drexa/server.go
Normal file
84
apps/backend/internal/drexa/server.go
Normal file
@@ -0,0 +1,84 @@
|
||||
package drexa
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
|
||||
"github.com/get-drexa/drexa/internal/auth"
|
||||
"github.com/get-drexa/drexa/internal/database"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
type ServerConfig struct {
|
||||
Port int
|
||||
PostgresURL string
|
||||
JWTIssuer string
|
||||
JWTAudience string
|
||||
JWTSecretKey []byte
|
||||
}
|
||||
|
||||
func NewServer(c ServerConfig) *fiber.App {
|
||||
app := fiber.New()
|
||||
db := database.NewFromPostgres(c.PostgresURL)
|
||||
|
||||
authService := auth.NewService(db, auth.TokenConfig{
|
||||
Issuer: c.JWTIssuer,
|
||||
Audience: c.JWTAudience,
|
||||
SecretKey: c.JWTSecretKey,
|
||||
})
|
||||
|
||||
api := app.Group("/api")
|
||||
auth.RegisterAPIRoutes(api, authService)
|
||||
|
||||
return app
|
||||
}
|
||||
|
||||
// ServerConfigFromEnv creates a ServerConfig from environment variables.
|
||||
func ServerConfigFromEnv() (*ServerConfig, error) {
|
||||
c := ServerConfig{
|
||||
PostgresURL: os.Getenv("POSTGRES_URL"),
|
||||
JWTIssuer: os.Getenv("JWT_ISSUER"),
|
||||
JWTAudience: os.Getenv("JWT_AUDIENCE"),
|
||||
}
|
||||
|
||||
errs := []error{}
|
||||
|
||||
keyHex := os.Getenv("JWT_SECRET_KEY")
|
||||
if keyHex == "" {
|
||||
errs = append(errs, errors.New("JWT_SECRET_KEY is required"))
|
||||
} else {
|
||||
k, err := hex.DecodeString(keyHex)
|
||||
if err != nil {
|
||||
errs = append(errs, fmt.Errorf("failed to decode JWT_SECRET_KEY: %w", err))
|
||||
}
|
||||
c.JWTSecretKey = k
|
||||
}
|
||||
|
||||
p, err := strconv.Atoi(os.Getenv("PORT"))
|
||||
if err != nil {
|
||||
errs = append(errs, fmt.Errorf("failed to parse PORT: %w", err))
|
||||
}
|
||||
c.Port = p
|
||||
|
||||
if c.PostgresURL == "" {
|
||||
errs = append(errs, errors.New("POSTGRES_URL is required"))
|
||||
}
|
||||
if c.JWTIssuer == "" {
|
||||
errs = append(errs, errors.New("JWT_ISSUER is required"))
|
||||
}
|
||||
if c.JWTAudience == "" {
|
||||
errs = append(errs, errors.New("JWT_AUDIENCE is required"))
|
||||
}
|
||||
if len(c.JWTSecretKey) == 0 {
|
||||
errs = append(errs, errors.New("JWT_SECRET_KEY is required"))
|
||||
}
|
||||
|
||||
if len(errs) > 0 {
|
||||
return nil, NewServerConfigError(errs...)
|
||||
}
|
||||
|
||||
return &c, nil
|
||||
}
|
||||
Reference in New Issue
Block a user