Files
kandev/apps/backend/internal/office/repository/sqlite/onboarding.go
T
2026-05-16 20:07:57 +01:00

75 lines
2.5 KiB
Go

package sqlite
import (
"context"
"database/sql"
"time"
)
// OnboardingState holds the persisted onboarding state for a workspace.
type OnboardingState struct {
WorkspaceID string `db:"workspace_id"`
Completed bool `db:"completed"`
CEOAgentID string `db:"ceo_agent_id"`
FirstTaskID string `db:"first_task_id"`
CompletedAt *time.Time `db:"completed_at"`
CreatedAt time.Time `db:"created_at"`
}
// GetOnboardingState returns the onboarding state for a workspace.
// Returns nil, nil if no row exists.
func (r *Repository) GetOnboardingState(ctx context.Context, workspaceID string) (*OnboardingState, error) {
var state OnboardingState
err := r.ro.QueryRowxContext(ctx, r.ro.Rebind(
`SELECT workspace_id, completed, ceo_agent_id, first_task_id, completed_at, created_at
FROM office_onboarding WHERE workspace_id = ?`), workspaceID).StructScan(&state)
if err == sql.ErrNoRows {
return nil, nil
}
if err != nil {
return nil, err
}
return &state, nil
}
// HasAnyCompletedOnboarding returns true if any workspace has completed onboarding.
func (r *Repository) HasAnyCompletedOnboarding(ctx context.Context) (bool, error) {
var count int
err := r.ro.QueryRowContext(ctx,
`SELECT COUNT(1) FROM office_onboarding WHERE completed = 1`).Scan(&count)
if err != nil {
return false, err
}
return count > 0, nil
}
// GetFirstCompletedOnboarding returns the first completed onboarding row, or nil.
func (r *Repository) GetFirstCompletedOnboarding(ctx context.Context) (*OnboardingState, error) {
var state OnboardingState
err := r.ro.QueryRowxContext(ctx,
`SELECT workspace_id, completed, ceo_agent_id, first_task_id, completed_at, created_at
FROM office_onboarding WHERE completed = 1 LIMIT 1`).StructScan(&state)
if err == sql.ErrNoRows {
return nil, nil
}
if err != nil {
return nil, err
}
return &state, nil
}
// MarkOnboardingComplete records that onboarding is finished for a workspace.
func (r *Repository) MarkOnboardingComplete(ctx context.Context, workspaceID, ceoAgentID, firstTaskID string) error {
now := time.Now().UTC()
_, err := r.db.ExecContext(ctx, r.db.Rebind(`
INSERT INTO office_onboarding (workspace_id, completed, ceo_agent_id, first_task_id, completed_at, created_at)
VALUES (?, 1, ?, ?, ?, ?)
ON CONFLICT(workspace_id) DO UPDATE SET
completed = 1,
ceo_agent_id = excluded.ceo_agent_id,
first_task_id = excluded.first_task_id,
completed_at = excluded.completed_at
`), workspaceID, ceoAgentID, firstTaskID, now, now)
return err
}