Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ APP_PORT=8080
APP_BASE_URL=http://localhost:8080
FRONTEND_URL=http://localhost:4200
LOG_LEVEL=info # debug | info | warn | error
ENV=development

# --- PostgreSQL ---
POSTGRES_HOST=localhost
Expand Down
83 changes: 82 additions & 1 deletion backend/cmd/api/main.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,55 @@
package api
// @title ZenReply API
// @version 1.0.0
// @description ZenReply is an intelligent Slack auto-reply system for deep work sessions.
// @termsOfService https://reply.zenkiet.com/terms
//
// @contact.name ZenKiet
// @contact.url https://zenkiet.com
// @contact.email kietgolx65234@gmail.com
//
// @license.name Apache 2.0
// @license.url https://www.apache.org/licenses/LICENSE-2.0.html
//
// @host localhost:8080
// @basePath /api/v1
// @schemes http https
//
// @securityDefinitions.apikey BearerAuth
// @in header
// @name Authorization
// @description Enter: Bearer <your-jwt-token>
//
// @tag.name system
// @tag.description System health and diagnostics
// @tag.name auth
// @tag.description Slack OAuth 2.0 authentication flow
// @tag.name users
// @tag.description User profile management
// @tag.name deep-work
// @tag.description Deep work session management
// @tag.name settings
// @tag.description User auto-reply configuration
// @tag.name logs
// @tag.description Auto-reply message history
// @tag.name slack
// @tag.description Slack Events API webhook

package main

import (
"context"
"log/slog"
"net/http"
"os"
"os/signal"
"syscall"
"time"

"github.com/kietle/zenreply/config"
"github.com/kietle/zenreply/handler"
"github.com/kietle/zenreply/pkg/database"
"github.com/kietle/zenreply/pkg/logger"
"github.com/kietle/zenreply/route"
)

func main() {
Expand Down Expand Up @@ -43,4 +86,42 @@ func main() {
log.Error("Failed to run migrations", "error", err)
}
log.Info("migrations applied successfully")

// --- Handler ---
h := handler.New(cfg, db, rdb)

// --- HTTP Server ---
router := route.Setup(cfg, h)
srv := &http.Server{
Addr: ":" + cfg.App.Port,
Handler: router,
ReadTimeout: 15 * time.Second,
WriteTimeout: 15 * time.Second,
IdleTimeout: 60 * time.Second,
}
go func() {
log.Info("HTTP server is running on port " + cfg.App.Port)
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Error("Failed to start HTTP server", "error", err)
os.Exit(1)
}
}()

// --- Graceful Shutdown ---
quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit

log.Info("Shutting down HTTP server...")
cancel()

shutdownCtx, shutdownCancel := context.WithTimeout(context.Background(), 30*time.Second)
defer shutdownCancel()

if err := srv.Shutdown(shutdownCtx); err != nil {
log.Error("server forced to shutdown", slog.String("error", err.Error()))
}

log.Info("HTTP server shutdown successfully")
os.Exit(0)
}
6 changes: 6 additions & 0 deletions backend/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ type AppConfig struct {
BaseURL string
FrontendURL string
LogLevel string
Env string
}

type PostgresConfig struct {
Expand Down Expand Up @@ -62,6 +63,7 @@ func Load() *Config {
BaseURL: getEnv("APP_BASE_URL", "http://localhost:8080"),
FrontendURL: getEnv("APP_FRONTEND_URL", "http://localhost:4200"),
LogLevel: getEnv("APP_LOG_LEVEL", "info"),
Env: getEnv("APP_ENV", "development"),
},
Postgres: PostgresConfig{
Host: getEnv("POSTGRES_HOST", "localhost"),
Expand All @@ -83,6 +85,10 @@ func Load() *Config {
}
}

func (c *AppConfig) IsProduction() bool {
return c.Env == "production"
}

func getEnv(key, fallback string) string {
if value, exists := os.LookupEnv(key); exists {
return value
Expand Down
48 changes: 46 additions & 2 deletions backend/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,61 @@ go 1.26.1
require github.com/jackc/pgx/v5 v5.8.0

require (
github.com/KyleBanks/depth v1.2.1 // indirect
github.com/PuerkitoBio/purell v1.1.1 // indirect
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
github.com/bytedance/gopkg v0.1.3 // indirect
github.com/bytedance/sonic v1.15.0 // indirect
github.com/bytedance/sonic/loader v0.5.0 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/cloudwego/base64x v0.1.6 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/gabriel-vasile/mimetype v1.4.12 // indirect
github.com/gin-contrib/sse v1.1.0 // indirect
github.com/go-openapi/jsonpointer v0.19.5 // indirect
github.com/go-openapi/jsonreference v0.19.6 // indirect
github.com/go-openapi/spec v0.20.4 // indirect
github.com/go-openapi/swag v0.19.15 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.30.1 // indirect
github.com/goccy/go-json v0.10.5 // indirect
github.com/goccy/go-yaml v1.19.2 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/cpuid/v2 v2.3.0 // indirect
github.com/leodido/go-urn v1.4.0 // indirect
github.com/mailru/easyjson v0.7.6 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
github.com/quic-go/qpack v0.6.0 // indirect
github.com/quic-go/quic-go v0.59.0 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.3.1 // indirect
go.mongodb.org/mongo-driver/v2 v2.5.0 // indirect
go.uber.org/atomic v1.11.0 // indirect
golang.org/x/arch v0.22.0 // indirect
golang.org/x/crypto v0.48.0 // indirect
golang.org/x/mod v0.32.0 // indirect
golang.org/x/net v0.51.0 // indirect
golang.org/x/sys v0.41.0 // indirect
golang.org/x/tools v0.41.0 // indirect
google.golang.org/protobuf v1.36.10 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
)

require (
github.com/gin-gonic/gin v1.12.0
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
github.com/jackc/puddle/v2 v2.2.2 // indirect
github.com/joho/godotenv v1.5.1
github.com/redis/go-redis/v9 v9.18.0
golang.org/x/sync v0.17.0 // indirect
golang.org/x/text v0.29.0 // indirect
github.com/swaggo/files v1.0.1
github.com/swaggo/gin-swagger v1.6.1
github.com/swaggo/swag v1.16.6
golang.org/x/sync v0.19.0 // indirect
golang.org/x/text v0.34.0 // indirect
)
Loading
Loading