renamed site directory to server
This commit is contained in:
@@ -7,6 +7,7 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"ruben/inventory2/internal/consts"
|
||||
|
||||
"github.com/jackc/pgx/v5"
|
||||
@@ -15,7 +16,8 @@ import (
|
||||
|
||||
type (
|
||||
Store struct {
|
||||
db *pgxpool.Pool
|
||||
log *slog.Logger
|
||||
db *pgxpool.Pool
|
||||
}
|
||||
|
||||
Account struct {
|
||||
@@ -59,9 +61,10 @@ type (
|
||||
}
|
||||
)
|
||||
|
||||
func NewStore(db *pgxpool.Pool) *Store {
|
||||
func NewStore(logger *slog.Logger, db *pgxpool.Pool) *Store {
|
||||
return &Store{
|
||||
db: db,
|
||||
log: logger,
|
||||
db: db,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
@@ -36,6 +37,7 @@ const (
|
||||
type (
|
||||
// Authenticator is used to authenticate our users.
|
||||
Authenticator struct {
|
||||
log *slog.Logger
|
||||
*oidc.Provider
|
||||
oauth2.Config
|
||||
db *pgxpool.Pool
|
||||
@@ -59,7 +61,11 @@ type (
|
||||
)
|
||||
|
||||
// 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(
|
||||
ctx,
|
||||
"https://"+AUTH0_DOMAIN+"/",
|
||||
@@ -69,6 +75,7 @@ func New(ctx context.Context, db *pgxpool.Pool) (*Authenticator, error) {
|
||||
}
|
||||
|
||||
return &Authenticator{
|
||||
log: logger,
|
||||
Provider: provider,
|
||||
Config: oauth2.Config{
|
||||
ClientID: AUTH0_CLIENT_ID,
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
@@ -32,6 +33,7 @@ import (
|
||||
|
||||
type (
|
||||
Platform struct {
|
||||
log *slog.Logger
|
||||
oAuthRedirectURI func(acctID int64) string
|
||||
apiKeystring string
|
||||
apiSharedSecret string
|
||||
@@ -63,8 +65,9 @@ const (
|
||||
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{
|
||||
log: logger,
|
||||
oAuthRedirectURI: oAuthRedirectURI,
|
||||
apiKeystring: apiKeystring,
|
||||
apiSharedSecret: apiSharedSecret,
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"time"
|
||||
|
||||
"github.com/jackc/pgx/v5"
|
||||
@@ -13,7 +14,8 @@ import (
|
||||
|
||||
type (
|
||||
Store struct {
|
||||
db *pgxpool.Pool
|
||||
log *slog.Logger
|
||||
db *pgxpool.Pool
|
||||
}
|
||||
|
||||
Event struct {
|
||||
@@ -25,9 +27,10 @@ type (
|
||||
}
|
||||
)
|
||||
|
||||
func NewStore(db *pgxpool.Pool) *Store {
|
||||
func NewStore(logger *slog.Logger, db *pgxpool.Pool) *Store {
|
||||
return &Store{
|
||||
db: db,
|
||||
log: logger,
|
||||
db: db,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package site
|
||||
package server
|
||||
|
||||
import (
|
||||
"errors"
|
||||
@@ -8,8 +8,8 @@ import (
|
||||
|
||||
"ruben/inventory2/internal/consts"
|
||||
"ruben/inventory2/internal/domains/accounts"
|
||||
"ruben/inventory2/internal/site/middleware"
|
||||
"ruben/inventory2/internal/site/response"
|
||||
"ruben/inventory2/internal/server/middleware"
|
||||
"ruben/inventory2/internal/server/response"
|
||||
)
|
||||
|
||||
// POST /accounts
|
||||
@@ -1,12 +1,12 @@
|
||||
package site
|
||||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"ruben/inventory2/internal/domains/authentication"
|
||||
"ruben/inventory2/internal/site/cookies"
|
||||
"ruben/inventory2/internal/site/response"
|
||||
"ruben/inventory2/internal/server/cookies"
|
||||
"ruben/inventory2/internal/server/response"
|
||||
)
|
||||
|
||||
// TODO: use a login/logout server? (prefix: '/auth'?)
|
||||
@@ -12,8 +12,8 @@ import (
|
||||
"ruben/inventory2/internal/consts"
|
||||
"ruben/inventory2/internal/domains/accounts"
|
||||
"ruben/inventory2/internal/domains/authentication"
|
||||
"ruben/inventory2/internal/site/cookies"
|
||||
"ruben/inventory2/internal/site/response"
|
||||
"ruben/inventory2/internal/server/cookies"
|
||||
"ruben/inventory2/internal/server/response"
|
||||
)
|
||||
|
||||
type (
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"ruben/inventory2/internal/site/redirect"
|
||||
"ruben/inventory2/internal/server/redirect"
|
||||
)
|
||||
|
||||
type (
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"ruben/inventory2/internal/site/redirect"
|
||||
"ruben/inventory2/internal/server/redirect"
|
||||
)
|
||||
|
||||
type (
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"ruben/inventory2/internal/site/redirect"
|
||||
"ruben/inventory2/internal/server/redirect"
|
||||
)
|
||||
|
||||
type (
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"ruben/inventory2/internal/site/redirect"
|
||||
"ruben/inventory2/internal/server/redirect"
|
||||
)
|
||||
|
||||
type (
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"ruben/inventory2/internal/site/redirect"
|
||||
"ruben/inventory2/internal/server/redirect"
|
||||
)
|
||||
|
||||
type (
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"ruben/inventory2/internal/site/redirect"
|
||||
"ruben/inventory2/internal/server/redirect"
|
||||
)
|
||||
|
||||
type (
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"ruben/inventory2/internal/site/redirect"
|
||||
"ruben/inventory2/internal/server/redirect"
|
||||
)
|
||||
|
||||
type (
|
||||
@@ -1,9 +1,10 @@
|
||||
package site
|
||||
package server
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"path"
|
||||
"strconv"
|
||||
@@ -16,11 +17,12 @@ import (
|
||||
"ruben/inventory2/internal/domains/authentication"
|
||||
etsy_platform "ruben/inventory2/internal/domains/platforms/etsy"
|
||||
"ruben/inventory2/internal/domains/raw_events"
|
||||
"ruben/inventory2/internal/site/middleware"
|
||||
"ruben/inventory2/internal/site/response"
|
||||
"ruben/inventory2/internal/server/middleware"
|
||||
"ruben/inventory2/internal/server/response"
|
||||
)
|
||||
|
||||
type Server struct {
|
||||
log *slog.Logger
|
||||
http.Handler
|
||||
contentDir string
|
||||
templater *templater.Templater
|
||||
@@ -32,6 +34,7 @@ type Server struct {
|
||||
}
|
||||
|
||||
func NewServer(
|
||||
logger *slog.Logger,
|
||||
contentDir string,
|
||||
rawEvents *raw_events.Store,
|
||||
accts *accounts.Store,
|
||||
@@ -53,6 +56,7 @@ func NewServer(
|
||||
})
|
||||
|
||||
s := &Server{
|
||||
log: logger,
|
||||
Handler: mux,
|
||||
contentDir: contentDir,
|
||||
templater: templater.NewTemplater(
|
||||
@@ -1,4 +1,4 @@
|
||||
package site
|
||||
package server
|
||||
|
||||
import (
|
||||
"errors"
|
||||
@@ -8,10 +8,11 @@ import (
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"ruben/inventory2/internal/site/middleware"
|
||||
"ruben/inventory2/internal/site/response"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"ruben/inventory2/internal/server/middleware"
|
||||
"ruben/inventory2/internal/server/response"
|
||||
)
|
||||
|
||||
// GET /
|
||||
@@ -3,6 +3,7 @@ package etsy
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
@@ -13,6 +14,7 @@ import (
|
||||
|
||||
type (
|
||||
Webhooks struct {
|
||||
log *slog.Logger
|
||||
cfg Config
|
||||
db *raw_events.Store
|
||||
etsy *etsy.Platform
|
||||
@@ -24,11 +26,13 @@ type (
|
||||
)
|
||||
|
||||
func NewWebhookHandler(
|
||||
logger *slog.Logger,
|
||||
db *raw_events.Store,
|
||||
platform *etsy.Platform,
|
||||
cfg Config,
|
||||
) http.Handler {
|
||||
h := Webhooks{
|
||||
log: logger,
|
||||
cfg: cfg,
|
||||
db: db,
|
||||
etsy: platform,
|
||||
|
||||
@@ -3,13 +3,14 @@ package tiktok
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"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.HandleFunc("POST /test", func(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package webhooks
|
||||
|
||||
import (
|
||||
"log/slog"
|
||||
"net/http"
|
||||
|
||||
etsy_platform "ruben/inventory2/internal/domains/platforms/etsy"
|
||||
@@ -14,12 +15,33 @@ type Config struct {
|
||||
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.Handle("/etsy/", http.StripPrefix("/etsy", etsy.NewWebhookHandler(eventsDB, etsyPlatform, cfg.Etsy)))
|
||||
wh.Handle("/tiktok/", http.StripPrefix("/tiktok", tiktok.NewWebhookHandler(eventsDB)))
|
||||
wh.Handle("/wix/", http.StripPrefix("/wix", wix.NewWebhookHandler(eventsDB)))
|
||||
wh.Handle(
|
||||
"/etsy/",
|
||||
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
|
||||
}
|
||||
|
||||
@@ -3,13 +3,14 @@ package wix
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"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.HandleFunc("POST /test", func(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
@@ -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 plantuml diagrams/*.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 (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
@@ -21,7 +22,7 @@ import (
|
||||
"ruben/inventory2/internal/domains/authentication"
|
||||
etsy_platform "ruben/inventory2/internal/domains/platforms/etsy"
|
||||
"ruben/inventory2/internal/domains/raw_events"
|
||||
"ruben/inventory2/internal/site"
|
||||
"ruben/inventory2/internal/server"
|
||||
"ruben/inventory2/internal/webhooks"
|
||||
etsy_webhooks "ruben/inventory2/internal/webhooks/etsy"
|
||||
)
|
||||
@@ -42,6 +43,17 @@ func runApp(ctx context.Context) error {
|
||||
ctx, shutdown := context.WithCancel(ctx)
|
||||
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
|
||||
|
||||
connPool, err := newPool(ctx)
|
||||
@@ -51,7 +63,7 @@ func runApp(ctx context.Context) error {
|
||||
|
||||
// start background processes
|
||||
|
||||
auth, err := authentication.New(ctx, connPool)
|
||||
auth, err := authentication.New(ctx, connPool, logger.WithGroup("*authentication.Authenticator"))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to construct authenticator: %w", err)
|
||||
}
|
||||
@@ -60,7 +72,7 @@ func runApp(ctx context.Context) error {
|
||||
|
||||
// start http server
|
||||
|
||||
srvErrCh := runServer(ctx, connPool, auth)
|
||||
srvErrCh := runServer(ctx, logger, connPool, auth)
|
||||
|
||||
// wait for interrupt signal or unrecoverable failure, then shutdown
|
||||
|
||||
@@ -127,10 +139,10 @@ func runAuthProcesses(ctx context.Context, auth *authentication.Authenticator) <
|
||||
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{
|
||||
Addr: ":8082", // local
|
||||
Handler: buildHTTPHandler(connPool, auth),
|
||||
Handler: buildHTTPHandler(logger, connPool, auth),
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
@@ -181,9 +193,10 @@ func runServer(ctx context.Context, connPool *pgxpool.Pool, auth *authentication
|
||||
return errCh
|
||||
}
|
||||
|
||||
func buildHTTPHandler(connPool *pgxpool.Pool, auth *authentication.Authenticator) http.Handler {
|
||||
eventsDB := raw_events.NewStore(connPool)
|
||||
func buildHTTPHandler(logger *slog.Logger, connPool *pgxpool.Pool, auth *authentication.Authenticator) http.Handler {
|
||||
eventsDB := raw_events.NewStore(logger.WithGroup("raw-event-store"), connPool)
|
||||
etsy := etsy_platform.NewPlatform(
|
||||
logger,
|
||||
func(acctID int64) string {
|
||||
return fmt.Sprintf("/oauth/account/%d/auth_code", acctID)
|
||||
},
|
||||
@@ -191,16 +204,28 @@ func buildHTTPHandler(connPool *pgxpool.Pool, auth *authentication.Authenticator
|
||||
etsyAPISharedSecret,
|
||||
connPool,
|
||||
)
|
||||
accts := accounts.NewStore(connPool)
|
||||
accts := accounts.NewStore(logger, connPool)
|
||||
|
||||
mux := http.NewServeMux()
|
||||
|
||||
mux.Handle("/webhooks/", http.StripPrefix("/webhooks", webhooks.New(eventsDB, etsy, webhooks.Config{
|
||||
Etsy: etsy_webhooks.Config{
|
||||
OAuthRedirectURIWithAcctIDParam: "/oauth/account/{acctID}/auth_code",
|
||||
mux.Handle("/webhooks/", http.StripPrefix("/webhooks", webhooks.New(
|
||||
logger.WithGroup("webhooks"),
|
||||
eventsDB,
|
||||
etsy,
|
||||
webhooks.Config{
|
||||
Etsy: etsy_webhooks.Config{
|
||||
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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user