package api import ( "context" "errors" "log/slog" "os" "strings" "queryorchestration/internal/client" "queryorchestration/internal/database/repository" "queryorchestration/internal/serviceconfig" "github.com/jackc/pgx/v5" "github.com/jackc/pgx/v5/pgconn" ) const ( localDevClientIDEnv = "LOCAL_DEV_CLIENT_ID" localDevClientNameEnv = "LOCAL_DEV_CLIENT_NAME" localDevEulaVersionEnv = "LOCAL_DEV_EULA_VERSION" localDevEulaTitleEnv = "LOCAL_DEV_EULA_TITLE" localDevEulaAutoAcceptSubjectEnv = "LOCAL_DEV_EULA_AUTO_ACCEPT_SUBJECT" localDevEulaAutoAcceptEmailEnv = "LOCAL_DEV_EULA_AUTO_ACCEPT_EMAIL" ) const localDevEulaContent = `

Acceptance of Terms

By accessing and using AArete DoczyAI in this local development environment, you agree to use the application only for authorized testing and evaluation.

Authorized Use

You are responsible for ensuring uploaded documents and generated outputs are appropriate for local development use and comply with applicable internal policies.

Data Handling

This local instance is intended for development workflows. Do not upload production, confidential, or regulated data unless the environment has been approved for that data.

No Warranty

This local development instance is provided as-is for testing. Features, data, and outputs may change during development.

` type localDevClientConfig interface { serviceconfig.ConfigProvider GetLogger() *slog.Logger } func ensureLocalDevClient(ctx context.Context, cfg localDevClientConfig) error { if strings.ToLower(os.Getenv("DISABLE_AUTH")) != "true" { return nil } clientID := strings.TrimSpace(os.Getenv(localDevClientIDEnv)) if clientID == "" { return nil } clientName := strings.TrimSpace(os.Getenv(localDevClientNameEnv)) if clientName == "" { clientName = clientID } _, err := cfg.GetDBQueries().GetClient(ctx, clientID) if err == nil { return nil } if !errors.Is(err, pgx.ErrNoRows) { var pgErr *pgconn.PgError if errors.As(err, &pgErr) && pgErr.Code == "42P01" { localDevBootstrapLogger(cfg).Warn("Skipping local dev client bootstrap because client tables are unavailable") return nil } return err } _, err = client.New(cfg).Create(ctx, client.CreateParams{ ID: clientID, Name: clientName, }) if err != nil { return err } localDevBootstrapLogger(cfg).Info("Created local dev client", slog.String("client_id", clientID)) return nil } func ensureLocalDevEula(ctx context.Context, cfg localDevClientConfig) error { if strings.ToLower(os.Getenv("DISABLE_AUTH")) != "true" { return nil } version := strings.TrimSpace(os.Getenv(localDevEulaVersionEnv)) if version == "" { return nil } title := strings.TrimSpace(os.Getenv(localDevEulaTitleEnv)) if title == "" { title = "AArete DoczyAI Terms of Use" } versionID, err := cfg.GetDBQueries().ActivateLocalDevEulaVersion(ctx, &repository.ActivateLocalDevEulaVersionParams{ Version: version, Title: title, Content: localDevEulaContent, }) if err != nil { var pgErr *pgconn.PgError if errors.As(err, &pgErr) && pgErr.Code == "42P01" { localDevBootstrapLogger(cfg).Warn("Skipping local dev EULA bootstrap because EULA tables are unavailable") return nil } return err } subject := strings.TrimSpace(os.Getenv(localDevEulaAutoAcceptSubjectEnv)) email := strings.TrimSpace(os.Getenv(localDevEulaAutoAcceptEmailEnv)) if subject != "" { if email == "" { email = subject } if err := cfg.GetDBQueries().CreateLocalDevEulaAgreement(ctx, &repository.CreateLocalDevEulaAgreementParams{ CognitoSubjectID: subject, UserEmail: email, EulaVersionID: versionID, }); err != nil { return err } } localDevBootstrapLogger(cfg).Info("Activated local dev EULA", slog.String("version", version)) return nil } func localDevBootstrapLogger(cfg localDevClientConfig) *slog.Logger { if logger := cfg.GetLogger(); logger != nil { return logger } return slog.Default() }