diff --git a/README.md b/README.md index 90d8546..25d90dc 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Keep It Up -A simple system that keeps an activity alive through periodic interaction and triggers an alert when it is left unattended for too long. +A system that coordinates periodic interactions across multiple devices and tracks when the next interaction is required. ## Tech Stack @@ -10,7 +10,35 @@ Go + SQLite Echo + SQLC + Goose ``` -## API +## CLI Management + +```text +Usage: + keepitup [args...] + +Nouns: + game add + update + delete + access grant + revoke + player add + rename + passwd + passwd-force + delete + auth validate-passwd + hash-passwd + check-passwd + data games + shared + interactions + session save + resume + pause +``` + +## HTTP API ```text POST /login username + password → set cookies diff --git a/internal/application/usecase/authentication.go b/internal/application/usecase/authentication.go index 784065c..a7c731b 100644 --- a/internal/application/usecase/authentication.go +++ b/internal/application/usecase/authentication.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "keep-it-up/internal/core/model" "keep-it-up/internal/infrastructure/database" "strings" @@ -71,6 +72,9 @@ func (uc *Authentication) CheckPlayerPassword(ctx context.Context, username stri return true, nil } -func (uc *Authentication) LoginPlayer(ctx context.Context, username string, password string) { - +func (uc *Authentication) LoginPlayer( + ctx context.Context, username string, password string, +) (model.AuthResult, error) { + // TODO: Implement + return model.AuthResult{}, nil } diff --git a/internal/application/usecase/data_fetching.go b/internal/application/usecase/data_fetching.go index 64546ca..e4ee3dc 100644 --- a/internal/application/usecase/data_fetching.go +++ b/internal/application/usecase/data_fetching.go @@ -13,7 +13,7 @@ func NewDataFetching() *DataFetching { } func (uc *DataFetching) ListPlayerGames( - ctx context.Context, gameId int64, playerId int64, + ctx context.Context, playerId int64, ) ([]database.Game, error) { return nil, nil } diff --git a/internal/core/interface/driver/driver.go b/internal/core/interface/driver/driver.go index ca2f579..87e5fc7 100644 --- a/internal/core/interface/driver/driver.go +++ b/internal/core/interface/driver/driver.go @@ -30,11 +30,11 @@ type Authentication interface { IsPasswordValid(password string) error GeneratePasswordHash(password string) (string, error) CheckPlayerPassword(ctx context.Context, username string, password string) (bool, error) - LoginPlayer(ctx context.Context, username string, password string) + LoginPlayer(ctx context.Context, username string, password string) (model.AuthResult, error) } type DataFetching interface { - ListPlayerGames(ctx context.Context, gameId int64, playerId int64) ([]database.Game, error) + ListPlayerGames(ctx context.Context, playerId int64) ([]database.Game, error) GetSharedData(ctx context.Context, gameId int64) (model.SharedData, error) ListInteractions(ctx context.Context, gameId int64, count int) ([]database.Interaction, error) } diff --git a/internal/core/model/model.go b/internal/core/model/model.go index 3116a36..d457b02 100644 --- a/internal/core/model/model.go +++ b/internal/core/model/model.go @@ -1,6 +1,9 @@ package model -import "time" +import ( + "keep-it-up/internal/infrastructure/database" + "time" +) type SharedDataStatus string @@ -17,3 +20,8 @@ type SharedData struct { LastSavedAt *time.Time LastPausedAt *time.Time } + +type AuthResult struct { + Token string + Player database.Player +} diff --git a/internal/infrastructure/driver/cli.go b/internal/infrastructure/driver/cli.go index b0b88cc..da3e616 100644 --- a/internal/infrastructure/driver/cli.go +++ b/internal/infrastructure/driver/cli.go @@ -22,10 +22,10 @@ var ( ErrWrongArgCount = errors.New("wrong number of arguments") ) -const usage = `keep-it-up — system management CLI +const usage = `keepitup --- system management CLI Usage: - keep-it-up [args...] + keepitup [args...] Nouns: game add @@ -38,18 +38,15 @@ Nouns: passwd passwd-force delete - auth validate-password - hash-password - check-password - data games + auth validate-passwd + hash-passwd + check-passwd + data games shared interactions session save resume pause - -Note: player login is not exposed here; it belongs to an interactive/session -driver, not an administrative one. ` // Deps groups the driver ports and I/O streams the CLI needs. It is a @@ -320,34 +317,34 @@ func (c *CLI) runAuth(ctx context.Context, args []string) error { } verb, rest := args[0], args[1:] switch verb { - case "validate-password": + case "validate-passwd": if len(rest) != 1 { - return wrongArgs("auth validate-password", "auth validate-password ") + return wrongArgs("auth validate-passwd", "auth validate-passwd ") } if err := c.d.Auth.IsPasswordValid(rest[0]); err != nil { - return fmt.Errorf("auth validate-password: %w", err) + return fmt.Errorf("auth validate-passwd: %w", err) } fmt.Fprintln(c.d.Stdout, "valid") return nil - case "hash-password": + case "hash-passwd": if len(rest) != 1 { - return wrongArgs("auth hash-password", "auth hash-password ") + return wrongArgs("auth hash-passwd", "auth hash-passwd ") } hash, err := c.d.Auth.GeneratePasswordHash(rest[0]) if err != nil { - return fmt.Errorf("auth hash-password: %w", err) + return fmt.Errorf("auth hash-passwd: %w", err) } fmt.Fprintln(c.d.Stdout, hash) return nil - case "check-password": + case "check-passwd": if len(rest) != 2 { - return wrongArgs("auth check-password", "auth check-password ") + return wrongArgs("auth check-passwd", "auth check-passwd ") } ok, err := c.d.Auth.CheckPlayerPassword(ctx, rest[0], rest[1]) if err != nil { - return fmt.Errorf("auth check-password: %w", err) + return fmt.Errorf("auth check-passwd: %w", err) } fmt.Fprintln(c.d.Stdout, ok) return nil @@ -366,18 +363,14 @@ func (c *CLI) runData(ctx context.Context, args []string) error { verb, rest := args[0], args[1:] switch verb { case "games": - if len(rest) != 2 { - return wrongArgs("data games", "data games ") - } - gameID, err := parseID(rest[0]) - if err != nil { - return fmt.Errorf("data games: %w", err) + if len(rest) != 1 { + return wrongArgs("data games", "data games ") } - playerID, err := parseID(rest[1]) + playerID, err := parseID(rest[0]) if err != nil { return fmt.Errorf("data games: %w", err) } - games, err := c.d.Data.ListPlayerGames(ctx, gameID, playerID) + games, err := c.d.Data.ListPlayerGames(ctx, playerID) if err != nil { return fmt.Errorf("data games: %w", err) }