renamed site directory to server

This commit is contained in:
2026-01-11 15:27:54 -07:00
parent 889aead6b6
commit ae01554b0b
65 changed files with 123 additions and 49 deletions
+4 -1
View File
@@ -7,6 +7,7 @@ import (
"context" "context"
"errors" "errors"
"fmt" "fmt"
"log/slog"
"ruben/inventory2/internal/consts" "ruben/inventory2/internal/consts"
"github.com/jackc/pgx/v5" "github.com/jackc/pgx/v5"
@@ -15,6 +16,7 @@ import (
type ( type (
Store struct { Store struct {
log *slog.Logger
db *pgxpool.Pool db *pgxpool.Pool
} }
@@ -59,8 +61,9 @@ type (
} }
) )
func NewStore(db *pgxpool.Pool) *Store { func NewStore(logger *slog.Logger, db *pgxpool.Pool) *Store {
return &Store{ return &Store{
log: logger,
db: db, db: db,
} }
} }
+8 -1
View File
@@ -5,6 +5,7 @@ import (
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
"log/slog"
"net/url" "net/url"
"time" "time"
@@ -36,6 +37,7 @@ const (
type ( type (
// Authenticator is used to authenticate our users. // Authenticator is used to authenticate our users.
Authenticator struct { Authenticator struct {
log *slog.Logger
*oidc.Provider *oidc.Provider
oauth2.Config oauth2.Config
db *pgxpool.Pool db *pgxpool.Pool
@@ -59,7 +61,11 @@ type (
) )
// New instantiates the *Authenticator. // New instantiates the *Authenticator.
func New(ctx context.Context, db *pgxpool.Pool) (*Authenticator, error) { func New(
ctx context.Context,
db *pgxpool.Pool,
logger *slog.Logger,
) (*Authenticator, error) {
provider, err := oidc.NewProvider( provider, err := oidc.NewProvider(
ctx, ctx,
"https://"+AUTH0_DOMAIN+"/", "https://"+AUTH0_DOMAIN+"/",
@@ -69,6 +75,7 @@ func New(ctx context.Context, db *pgxpool.Pool) (*Authenticator, error) {
} }
return &Authenticator{ return &Authenticator{
log: logger,
Provider: provider, Provider: provider,
Config: oauth2.Config{ Config: oauth2.Config{
ClientID: AUTH0_CLIENT_ID, ClientID: AUTH0_CLIENT_ID,
+4 -1
View File
@@ -7,6 +7,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"io" "io"
"log/slog"
"net/http" "net/http"
"net/url" "net/url"
"strconv" "strconv"
@@ -32,6 +33,7 @@ import (
type ( type (
Platform struct { Platform struct {
log *slog.Logger
oAuthRedirectURI func(acctID int64) string oAuthRedirectURI func(acctID int64) string
apiKeystring string apiKeystring string
apiSharedSecret string apiSharedSecret string
@@ -63,8 +65,9 @@ const (
scopeTransactionsWrite = "transactions_w" // Update a member's sales data. scopeTransactionsWrite = "transactions_w" // Update a member's sales data.
) )
func NewPlatform(oAuthRedirectURI func(acctID int64) string, apiKeystring, apiSharedSecret string, db *pgxpool.Pool) *Platform { func NewPlatform(logger *slog.Logger, oAuthRedirectURI func(acctID int64) string, apiKeystring, apiSharedSecret string, db *pgxpool.Pool) *Platform {
return &Platform{ return &Platform{
log: logger,
oAuthRedirectURI: oAuthRedirectURI, oAuthRedirectURI: oAuthRedirectURI,
apiKeystring: apiKeystring, apiKeystring: apiKeystring,
apiSharedSecret: apiSharedSecret, apiSharedSecret: apiSharedSecret,
+4 -1
View File
@@ -4,6 +4,7 @@ import (
"context" "context"
"encoding/json" "encoding/json"
"fmt" "fmt"
"log/slog"
"time" "time"
"github.com/jackc/pgx/v5" "github.com/jackc/pgx/v5"
@@ -13,6 +14,7 @@ import (
type ( type (
Store struct { Store struct {
log *slog.Logger
db *pgxpool.Pool db *pgxpool.Pool
} }
@@ -25,8 +27,9 @@ type (
} }
) )
func NewStore(db *pgxpool.Pool) *Store { func NewStore(logger *slog.Logger, db *pgxpool.Pool) *Store {
return &Store{ return &Store{
log: logger,
db: db, db: db,
} }
} }
@@ -1,4 +1,4 @@
package site package server
import ( import (
"errors" "errors"
@@ -8,8 +8,8 @@ import (
"ruben/inventory2/internal/consts" "ruben/inventory2/internal/consts"
"ruben/inventory2/internal/domains/accounts" "ruben/inventory2/internal/domains/accounts"
"ruben/inventory2/internal/site/middleware" "ruben/inventory2/internal/server/middleware"
"ruben/inventory2/internal/site/response" "ruben/inventory2/internal/server/response"
) )
// POST /accounts // POST /accounts
@@ -1,12 +1,12 @@
package site package server
import ( import (
"context" "context"
"fmt" "fmt"
"net/http" "net/http"
"ruben/inventory2/internal/domains/authentication" "ruben/inventory2/internal/domains/authentication"
"ruben/inventory2/internal/site/cookies" "ruben/inventory2/internal/server/cookies"
"ruben/inventory2/internal/site/response" "ruben/inventory2/internal/server/response"
) )
// TODO: use a login/logout server? (prefix: '/auth'?) // TODO: use a login/logout server? (prefix: '/auth'?)
@@ -12,8 +12,8 @@ import (
"ruben/inventory2/internal/consts" "ruben/inventory2/internal/consts"
"ruben/inventory2/internal/domains/accounts" "ruben/inventory2/internal/domains/accounts"
"ruben/inventory2/internal/domains/authentication" "ruben/inventory2/internal/domains/authentication"
"ruben/inventory2/internal/site/cookies" "ruben/inventory2/internal/server/cookies"
"ruben/inventory2/internal/site/response" "ruben/inventory2/internal/server/response"
) )
type ( type (
@@ -4,7 +4,7 @@ import (
"fmt" "fmt"
"io" "io"
"net/http" "net/http"
"ruben/inventory2/internal/site/redirect" "ruben/inventory2/internal/server/redirect"
) )
type ( type (
@@ -4,7 +4,7 @@ import (
"fmt" "fmt"
"io" "io"
"net/http" "net/http"
"ruben/inventory2/internal/site/redirect" "ruben/inventory2/internal/server/redirect"
) )
type ( type (
@@ -5,7 +5,7 @@ import (
"fmt" "fmt"
"io" "io"
"net/http" "net/http"
"ruben/inventory2/internal/site/redirect" "ruben/inventory2/internal/server/redirect"
) )
type ( type (
@@ -6,7 +6,7 @@ import (
"fmt" "fmt"
"io" "io"
"net/http" "net/http"
"ruben/inventory2/internal/site/redirect" "ruben/inventory2/internal/server/redirect"
) )
type ( type (
@@ -4,7 +4,7 @@ import (
"fmt" "fmt"
"io" "io"
"net/http" "net/http"
"ruben/inventory2/internal/site/redirect" "ruben/inventory2/internal/server/redirect"
) )
type ( type (
@@ -4,7 +4,7 @@ import (
"io" "io"
"net/http" "net/http"
"ruben/inventory2/internal/site/redirect" "ruben/inventory2/internal/server/redirect"
) )
type ( type (
@@ -5,7 +5,7 @@ import (
"io" "io"
"net/http" "net/http"
"ruben/inventory2/internal/site/redirect" "ruben/inventory2/internal/server/redirect"
) )
type ( type (
@@ -1,9 +1,10 @@
package site package server
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"html/template" "html/template"
"log/slog"
"net/http" "net/http"
"path" "path"
"strconv" "strconv"
@@ -16,11 +17,12 @@ import (
"ruben/inventory2/internal/domains/authentication" "ruben/inventory2/internal/domains/authentication"
etsy_platform "ruben/inventory2/internal/domains/platforms/etsy" etsy_platform "ruben/inventory2/internal/domains/platforms/etsy"
"ruben/inventory2/internal/domains/raw_events" "ruben/inventory2/internal/domains/raw_events"
"ruben/inventory2/internal/site/middleware" "ruben/inventory2/internal/server/middleware"
"ruben/inventory2/internal/site/response" "ruben/inventory2/internal/server/response"
) )
type Server struct { type Server struct {
log *slog.Logger
http.Handler http.Handler
contentDir string contentDir string
templater *templater.Templater templater *templater.Templater
@@ -32,6 +34,7 @@ type Server struct {
} }
func NewServer( func NewServer(
logger *slog.Logger,
contentDir string, contentDir string,
rawEvents *raw_events.Store, rawEvents *raw_events.Store,
accts *accounts.Store, accts *accounts.Store,
@@ -53,6 +56,7 @@ func NewServer(
}) })
s := &Server{ s := &Server{
log: logger,
Handler: mux, Handler: mux,
contentDir: contentDir, contentDir: contentDir,
templater: templater.NewTemplater( templater: templater.NewTemplater(
@@ -1,4 +1,4 @@
package site package server
import ( import (
"errors" "errors"
@@ -8,10 +8,11 @@ import (
"os" "os"
"path" "path"
"path/filepath" "path/filepath"
"ruben/inventory2/internal/site/middleware"
"ruben/inventory2/internal/site/response"
"strconv" "strconv"
"strings" "strings"
"ruben/inventory2/internal/server/middleware"
"ruben/inventory2/internal/server/response"
) )
// GET / // GET /
+4
View File
@@ -3,6 +3,7 @@ package etsy
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"log/slog"
"net/http" "net/http"
"strconv" "strconv"
"time" "time"
@@ -13,6 +14,7 @@ import (
type ( type (
Webhooks struct { Webhooks struct {
log *slog.Logger
cfg Config cfg Config
db *raw_events.Store db *raw_events.Store
etsy *etsy.Platform etsy *etsy.Platform
@@ -24,11 +26,13 @@ type (
) )
func NewWebhookHandler( func NewWebhookHandler(
logger *slog.Logger,
db *raw_events.Store, db *raw_events.Store,
platform *etsy.Platform, platform *etsy.Platform,
cfg Config, cfg Config,
) http.Handler { ) http.Handler {
h := Webhooks{ h := Webhooks{
log: logger,
cfg: cfg, cfg: cfg,
db: db, db: db,
etsy: platform, etsy: platform,
+2 -1
View File
@@ -3,13 +3,14 @@ package tiktok
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"log/slog"
"net/http" "net/http"
"time" "time"
"ruben/inventory2/internal/domains/raw_events" "ruben/inventory2/internal/domains/raw_events"
) )
func NewWebhookHandler(db *raw_events.Store) http.Handler { func NewWebhookHandler(logger *slog.Logger, db *raw_events.Store) http.Handler {
mux := http.NewServeMux() mux := http.NewServeMux()
mux.HandleFunc("POST /test", func(w http.ResponseWriter, r *http.Request) { mux.HandleFunc("POST /test", func(w http.ResponseWriter, r *http.Request) {
+26 -4
View File
@@ -1,6 +1,7 @@
package webhooks package webhooks
import ( import (
"log/slog"
"net/http" "net/http"
etsy_platform "ruben/inventory2/internal/domains/platforms/etsy" etsy_platform "ruben/inventory2/internal/domains/platforms/etsy"
@@ -14,12 +15,33 @@ type Config struct {
Etsy etsy.Config Etsy etsy.Config
} }
func New(eventsDB *raw_events.Store, etsyPlatform *etsy_platform.Platform, cfg Config) http.Handler { // TODO: just move over to the 'site' package, and then consider renaming the site package to something else?
func New(logger *slog.Logger, eventsDB *raw_events.Store, etsyPlatform *etsy_platform.Platform, cfg Config) http.Handler {
wh := http.NewServeMux() wh := http.NewServeMux()
wh.Handle("/etsy/", http.StripPrefix("/etsy", etsy.NewWebhookHandler(eventsDB, etsyPlatform, cfg.Etsy))) wh.Handle(
wh.Handle("/tiktok/", http.StripPrefix("/tiktok", tiktok.NewWebhookHandler(eventsDB))) "/etsy/",
wh.Handle("/wix/", http.StripPrefix("/wix", wix.NewWebhookHandler(eventsDB))) http.StripPrefix("/etsy", etsy.NewWebhookHandler(
logger.WithGroup("etsy"),
eventsDB,
etsyPlatform,
cfg.Etsy,
)),
)
wh.Handle(
"/tiktok/",
http.StripPrefix("/tiktok", tiktok.NewWebhookHandler(
logger.WithGroup("tiktok"),
eventsDB,
)),
)
wh.Handle(
"/wix/",
http.StripPrefix("/wix", wix.NewWebhookHandler(
logger.WithGroup("wix"),
eventsDB,
)),
)
return wh return wh
} }
+2 -1
View File
@@ -3,13 +3,14 @@ package wix
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"log/slog"
"net/http" "net/http"
"time" "time"
"ruben/inventory2/internal/domains/raw_events" "ruben/inventory2/internal/domains/raw_events"
) )
func NewWebhookHandler(db *raw_events.Store) http.Handler { func NewWebhookHandler(logger *slog.Logger, db *raw_events.Store) http.Handler {
mux := http.NewServeMux() mux := http.NewServeMux()
mux.HandleFunc("POST /test", func(w http.ResponseWriter, r *http.Request) { mux.HandleFunc("POST /test", func(w http.ResponseWriter, r *http.Request) {
+37 -12
View File
@@ -3,12 +3,13 @@ package main
//go:generate planter postgres://planter:planter@localhost:5432/inventory_2?sslmode=disable -o diagrams/database_schema.uml //go:generate planter postgres://planter:planter@localhost:5432/inventory_2?sslmode=disable -o diagrams/database_schema.uml
//go:generate plantuml diagrams/*.uml -tsvg //go:generate plantuml diagrams/*.uml -tsvg
//go:generate plantuml diagrams/etsy/*.uml -tsvg //go:generate plantuml diagrams/etsy/*.uml -tsvg
//go:generate npx @tailwindcss/cli -i styles/source.css -o styles/index.css --cwd ./internal/site //go:generate npx @tailwindcss/cli -i styles/source.css -o styles/index.css --cwd ./internal/server
import ( import (
"context" "context"
"errors" "errors"
"fmt" "fmt"
"log/slog"
"net/http" "net/http"
"os" "os"
"os/signal" "os/signal"
@@ -21,7 +22,7 @@ import (
"ruben/inventory2/internal/domains/authentication" "ruben/inventory2/internal/domains/authentication"
etsy_platform "ruben/inventory2/internal/domains/platforms/etsy" etsy_platform "ruben/inventory2/internal/domains/platforms/etsy"
"ruben/inventory2/internal/domains/raw_events" "ruben/inventory2/internal/domains/raw_events"
"ruben/inventory2/internal/site" "ruben/inventory2/internal/server"
"ruben/inventory2/internal/webhooks" "ruben/inventory2/internal/webhooks"
etsy_webhooks "ruben/inventory2/internal/webhooks/etsy" etsy_webhooks "ruben/inventory2/internal/webhooks/etsy"
) )
@@ -42,6 +43,17 @@ func runApp(ctx context.Context) error {
ctx, shutdown := context.WithCancel(ctx) ctx, shutdown := context.WithCancel(ctx)
defer shutdown() defer shutdown()
logger := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{
AddSource: true,
Level: slog.LevelDebug,
ReplaceAttr: func(groups []string, a slog.Attr) slog.Attr {
fmt.Println("slog groups:", groups)
fmt.Println("slog attr:", a)
// TODO: not sure if this will be needed, but keep around until known.
return a
},
}))
// connect to the database // connect to the database
connPool, err := newPool(ctx) connPool, err := newPool(ctx)
@@ -51,7 +63,7 @@ func runApp(ctx context.Context) error {
// start background processes // start background processes
auth, err := authentication.New(ctx, connPool) auth, err := authentication.New(ctx, connPool, logger.WithGroup("*authentication.Authenticator"))
if err != nil { if err != nil {
return fmt.Errorf("failed to construct authenticator: %w", err) return fmt.Errorf("failed to construct authenticator: %w", err)
} }
@@ -60,7 +72,7 @@ func runApp(ctx context.Context) error {
// start http server // start http server
srvErrCh := runServer(ctx, connPool, auth) srvErrCh := runServer(ctx, logger, connPool, auth)
// wait for interrupt signal or unrecoverable failure, then shutdown // wait for interrupt signal or unrecoverable failure, then shutdown
@@ -127,10 +139,10 @@ func runAuthProcesses(ctx context.Context, auth *authentication.Authenticator) <
return errCh return errCh
} }
func runServer(ctx context.Context, connPool *pgxpool.Pool, auth *authentication.Authenticator) <-chan error { func runServer(ctx context.Context, logger *slog.Logger, connPool *pgxpool.Pool, auth *authentication.Authenticator) <-chan error {
srv := &http.Server{ srv := &http.Server{
Addr: ":8082", // local Addr: ":8082", // local
Handler: buildHTTPHandler(connPool, auth), Handler: buildHTTPHandler(logger, connPool, auth),
} }
ctx, cancel := context.WithCancel(ctx) ctx, cancel := context.WithCancel(ctx)
@@ -181,9 +193,10 @@ func runServer(ctx context.Context, connPool *pgxpool.Pool, auth *authentication
return errCh return errCh
} }
func buildHTTPHandler(connPool *pgxpool.Pool, auth *authentication.Authenticator) http.Handler { func buildHTTPHandler(logger *slog.Logger, connPool *pgxpool.Pool, auth *authentication.Authenticator) http.Handler {
eventsDB := raw_events.NewStore(connPool) eventsDB := raw_events.NewStore(logger.WithGroup("raw-event-store"), connPool)
etsy := etsy_platform.NewPlatform( etsy := etsy_platform.NewPlatform(
logger,
func(acctID int64) string { func(acctID int64) string {
return fmt.Sprintf("/oauth/account/%d/auth_code", acctID) return fmt.Sprintf("/oauth/account/%d/auth_code", acctID)
}, },
@@ -191,16 +204,28 @@ func buildHTTPHandler(connPool *pgxpool.Pool, auth *authentication.Authenticator
etsyAPISharedSecret, etsyAPISharedSecret,
connPool, connPool,
) )
accts := accounts.NewStore(connPool) accts := accounts.NewStore(logger, connPool)
mux := http.NewServeMux() mux := http.NewServeMux()
mux.Handle("/webhooks/", http.StripPrefix("/webhooks", webhooks.New(eventsDB, etsy, webhooks.Config{ mux.Handle("/webhooks/", http.StripPrefix("/webhooks", webhooks.New(
logger.WithGroup("webhooks"),
eventsDB,
etsy,
webhooks.Config{
Etsy: etsy_webhooks.Config{ Etsy: etsy_webhooks.Config{
OAuthRedirectURIWithAcctIDParam: "/oauth/account/{acctID}/auth_code", OAuthRedirectURIWithAcctIDParam: "/oauth/account/{acctID}/auth_code",
}, },
}))) },
mux.Handle("/", site.NewServer("./internal/site", eventsDB, accts, etsy, auth)) )))
mux.Handle("/", server.NewServer(
logger.WithGroup("server"),
"./internal/server",
eventsDB,
accts,
etsy,
auth,
))
return mux return mux
} }