fix: resolve merge conflicts with main, preserve PAT functionality
- Resolve conflicts in CLAUDE.md, client.ts, settings/page.tsx - Migrate PAT types and API methods to @/shared/types + @/shared/api architecture - Restore simplified login flow (login page, auth store, tests) - Fix issue detail comment submit test (use fireEvent + useRef for mock) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
commit
f70b34a50f
45 changed files with 2044 additions and 261 deletions
|
|
@ -179,6 +179,18 @@ type Member struct {
|
|||
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
||||
}
|
||||
|
||||
type PersonalAccessToken struct {
|
||||
ID pgtype.UUID `json:"id"`
|
||||
UserID pgtype.UUID `json:"user_id"`
|
||||
Name string `json:"name"`
|
||||
TokenHash string `json:"token_hash"`
|
||||
TokenPrefix string `json:"token_prefix"`
|
||||
ExpiresAt pgtype.Timestamptz `json:"expires_at"`
|
||||
LastUsedAt pgtype.Timestamptz `json:"last_used_at"`
|
||||
Revoked bool `json:"revoked"`
|
||||
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
||||
}
|
||||
|
||||
type Skill struct {
|
||||
ID pgtype.UUID `json:"id"`
|
||||
WorkspaceID pgtype.UUID `json:"workspace_id"`
|
||||
|
|
@ -209,6 +221,16 @@ type User struct {
|
|||
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
|
||||
}
|
||||
|
||||
type VerificationCode struct {
|
||||
ID pgtype.UUID `json:"id"`
|
||||
Email string `json:"email"`
|
||||
Code string `json:"code"`
|
||||
ExpiresAt pgtype.Timestamptz `json:"expires_at"`
|
||||
Used bool `json:"used"`
|
||||
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
||||
Attempts int32 `json:"attempts"`
|
||||
}
|
||||
|
||||
type Workspace struct {
|
||||
ID pgtype.UUID `json:"id"`
|
||||
Name string `json:"name"`
|
||||
|
|
|
|||
137
server/pkg/db/generated/personal_access_token.sql.go
Normal file
137
server/pkg/db/generated/personal_access_token.sql.go
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
// Code generated by sqlc. DO NOT EDIT.
|
||||
// versions:
|
||||
// sqlc v1.30.0
|
||||
// source: personal_access_token.sql
|
||||
|
||||
package db
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
)
|
||||
|
||||
const createPersonalAccessToken = `-- name: CreatePersonalAccessToken :one
|
||||
INSERT INTO personal_access_token (user_id, name, token_hash, token_prefix, expires_at)
|
||||
VALUES ($1, $2, $3, $4, $5)
|
||||
RETURNING id, user_id, name, token_hash, token_prefix, expires_at, last_used_at, revoked, created_at
|
||||
`
|
||||
|
||||
type CreatePersonalAccessTokenParams struct {
|
||||
UserID pgtype.UUID `json:"user_id"`
|
||||
Name string `json:"name"`
|
||||
TokenHash string `json:"token_hash"`
|
||||
TokenPrefix string `json:"token_prefix"`
|
||||
ExpiresAt pgtype.Timestamptz `json:"expires_at"`
|
||||
}
|
||||
|
||||
func (q *Queries) CreatePersonalAccessToken(ctx context.Context, arg CreatePersonalAccessTokenParams) (PersonalAccessToken, error) {
|
||||
row := q.db.QueryRow(ctx, createPersonalAccessToken,
|
||||
arg.UserID,
|
||||
arg.Name,
|
||||
arg.TokenHash,
|
||||
arg.TokenPrefix,
|
||||
arg.ExpiresAt,
|
||||
)
|
||||
var i PersonalAccessToken
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.UserID,
|
||||
&i.Name,
|
||||
&i.TokenHash,
|
||||
&i.TokenPrefix,
|
||||
&i.ExpiresAt,
|
||||
&i.LastUsedAt,
|
||||
&i.Revoked,
|
||||
&i.CreatedAt,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const getPersonalAccessTokenByHash = `-- name: GetPersonalAccessTokenByHash :one
|
||||
SELECT id, user_id, name, token_hash, token_prefix, expires_at, last_used_at, revoked, created_at FROM personal_access_token
|
||||
WHERE token_hash = $1
|
||||
AND revoked = FALSE
|
||||
AND (expires_at IS NULL OR expires_at > now())
|
||||
`
|
||||
|
||||
func (q *Queries) GetPersonalAccessTokenByHash(ctx context.Context, tokenHash string) (PersonalAccessToken, error) {
|
||||
row := q.db.QueryRow(ctx, getPersonalAccessTokenByHash, tokenHash)
|
||||
var i PersonalAccessToken
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.UserID,
|
||||
&i.Name,
|
||||
&i.TokenHash,
|
||||
&i.TokenPrefix,
|
||||
&i.ExpiresAt,
|
||||
&i.LastUsedAt,
|
||||
&i.Revoked,
|
||||
&i.CreatedAt,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const listPersonalAccessTokensByUser = `-- name: ListPersonalAccessTokensByUser :many
|
||||
SELECT id, user_id, name, token_hash, token_prefix, expires_at, last_used_at, revoked, created_at FROM personal_access_token
|
||||
WHERE user_id = $1
|
||||
AND revoked = FALSE
|
||||
ORDER BY created_at DESC
|
||||
`
|
||||
|
||||
func (q *Queries) ListPersonalAccessTokensByUser(ctx context.Context, userID pgtype.UUID) ([]PersonalAccessToken, error) {
|
||||
rows, err := q.db.Query(ctx, listPersonalAccessTokensByUser, userID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
items := []PersonalAccessToken{}
|
||||
for rows.Next() {
|
||||
var i PersonalAccessToken
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.UserID,
|
||||
&i.Name,
|
||||
&i.TokenHash,
|
||||
&i.TokenPrefix,
|
||||
&i.ExpiresAt,
|
||||
&i.LastUsedAt,
|
||||
&i.Revoked,
|
||||
&i.CreatedAt,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const revokePersonalAccessToken = `-- name: RevokePersonalAccessToken :exec
|
||||
UPDATE personal_access_token
|
||||
SET revoked = TRUE
|
||||
WHERE id = $1 AND user_id = $2
|
||||
`
|
||||
|
||||
type RevokePersonalAccessTokenParams struct {
|
||||
ID pgtype.UUID `json:"id"`
|
||||
UserID pgtype.UUID `json:"user_id"`
|
||||
}
|
||||
|
||||
func (q *Queries) RevokePersonalAccessToken(ctx context.Context, arg RevokePersonalAccessTokenParams) error {
|
||||
_, err := q.db.Exec(ctx, revokePersonalAccessToken, arg.ID, arg.UserID)
|
||||
return err
|
||||
}
|
||||
|
||||
const updatePersonalAccessTokenLastUsed = `-- name: UpdatePersonalAccessTokenLastUsed :exec
|
||||
UPDATE personal_access_token
|
||||
SET last_used_at = now()
|
||||
WHERE id = $1
|
||||
`
|
||||
|
||||
func (q *Queries) UpdatePersonalAccessTokenLastUsed(ctx context.Context, id pgtype.UUID) error {
|
||||
_, err := q.db.Exec(ctx, updatePersonalAccessTokenLastUsed, id)
|
||||
return err
|
||||
}
|
||||
118
server/pkg/db/generated/verification_code.sql.go
Normal file
118
server/pkg/db/generated/verification_code.sql.go
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
// Code generated by sqlc. DO NOT EDIT.
|
||||
// versions:
|
||||
// sqlc v1.30.0
|
||||
// source: verification_code.sql
|
||||
|
||||
package db
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
)
|
||||
|
||||
const createVerificationCode = `-- name: CreateVerificationCode :one
|
||||
INSERT INTO verification_code (email, code, expires_at)
|
||||
VALUES ($1, $2, $3)
|
||||
RETURNING id, email, code, expires_at, used, created_at, attempts
|
||||
`
|
||||
|
||||
type CreateVerificationCodeParams struct {
|
||||
Email string `json:"email"`
|
||||
Code string `json:"code"`
|
||||
ExpiresAt pgtype.Timestamptz `json:"expires_at"`
|
||||
}
|
||||
|
||||
func (q *Queries) CreateVerificationCode(ctx context.Context, arg CreateVerificationCodeParams) (VerificationCode, error) {
|
||||
row := q.db.QueryRow(ctx, createVerificationCode, arg.Email, arg.Code, arg.ExpiresAt)
|
||||
var i VerificationCode
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.Email,
|
||||
&i.Code,
|
||||
&i.ExpiresAt,
|
||||
&i.Used,
|
||||
&i.CreatedAt,
|
||||
&i.Attempts,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const deleteExpiredVerificationCodes = `-- name: DeleteExpiredVerificationCodes :exec
|
||||
DELETE FROM verification_code
|
||||
WHERE expires_at < now() - interval '1 hour'
|
||||
`
|
||||
|
||||
func (q *Queries) DeleteExpiredVerificationCodes(ctx context.Context) error {
|
||||
_, err := q.db.Exec(ctx, deleteExpiredVerificationCodes)
|
||||
return err
|
||||
}
|
||||
|
||||
const getLatestCodeByEmail = `-- name: GetLatestCodeByEmail :one
|
||||
SELECT id, email, code, expires_at, used, created_at, attempts FROM verification_code
|
||||
WHERE email = $1
|
||||
ORDER BY created_at DESC
|
||||
LIMIT 1
|
||||
`
|
||||
|
||||
func (q *Queries) GetLatestCodeByEmail(ctx context.Context, email string) (VerificationCode, error) {
|
||||
row := q.db.QueryRow(ctx, getLatestCodeByEmail, email)
|
||||
var i VerificationCode
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.Email,
|
||||
&i.Code,
|
||||
&i.ExpiresAt,
|
||||
&i.Used,
|
||||
&i.CreatedAt,
|
||||
&i.Attempts,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const getLatestVerificationCode = `-- name: GetLatestVerificationCode :one
|
||||
SELECT id, email, code, expires_at, used, created_at, attempts FROM verification_code
|
||||
WHERE email = $1
|
||||
AND used = FALSE
|
||||
AND expires_at > now()
|
||||
AND attempts < 5
|
||||
ORDER BY created_at DESC
|
||||
LIMIT 1
|
||||
`
|
||||
|
||||
func (q *Queries) GetLatestVerificationCode(ctx context.Context, email string) (VerificationCode, error) {
|
||||
row := q.db.QueryRow(ctx, getLatestVerificationCode, email)
|
||||
var i VerificationCode
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.Email,
|
||||
&i.Code,
|
||||
&i.ExpiresAt,
|
||||
&i.Used,
|
||||
&i.CreatedAt,
|
||||
&i.Attempts,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const incrementVerificationCodeAttempts = `-- name: IncrementVerificationCodeAttempts :exec
|
||||
UPDATE verification_code
|
||||
SET attempts = attempts + 1
|
||||
WHERE id = $1
|
||||
`
|
||||
|
||||
func (q *Queries) IncrementVerificationCodeAttempts(ctx context.Context, id pgtype.UUID) error {
|
||||
_, err := q.db.Exec(ctx, incrementVerificationCodeAttempts, id)
|
||||
return err
|
||||
}
|
||||
|
||||
const markVerificationCodeUsed = `-- name: MarkVerificationCodeUsed :exec
|
||||
UPDATE verification_code
|
||||
SET used = TRUE
|
||||
WHERE id = $1
|
||||
`
|
||||
|
||||
func (q *Queries) MarkVerificationCodeUsed(ctx context.Context, id pgtype.UUID) error {
|
||||
_, err := q.db.Exec(ctx, markVerificationCodeUsed, id)
|
||||
return err
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue