feat: Add role-based access control to database schema
- Add role column to users table with admin/user constraint - Add added_by_admin_id column to ebooks table for tracking - Add constraint to ensure only admins can manage folders - Update all SQL queries to include role field - Regenerate database models with new schema
This commit is contained in:
@@ -9,6 +9,7 @@ CREATE TABLE users (
|
|||||||
password_hash VARCHAR(255) NOT NULL,
|
password_hash VARCHAR(255) NOT NULL,
|
||||||
first_name VARCHAR(255),
|
first_name VARCHAR(255),
|
||||||
last_name VARCHAR(255),
|
last_name VARCHAR(255),
|
||||||
|
role VARCHAR(20) NOT NULL DEFAULT 'user' CHECK (role IN ('admin', 'user')),
|
||||||
theme VARCHAR(50) DEFAULT 'tokyo-night',
|
theme VARCHAR(50) DEFAULT 'tokyo-night',
|
||||||
scan_frequency_minutes INTEGER DEFAULT 60,
|
scan_frequency_minutes INTEGER DEFAULT 60,
|
||||||
auto_scan_enabled BOOLEAN DEFAULT true,
|
auto_scan_enabled BOOLEAN DEFAULT true,
|
||||||
@@ -34,6 +35,7 @@ CREATE TABLE ebooks (
|
|||||||
date_published DATE,
|
date_published DATE,
|
||||||
publisher VARCHAR(255),
|
publisher VARCHAR(255),
|
||||||
contributors TEXT,
|
contributors TEXT,
|
||||||
|
added_by_admin_id UUID REFERENCES users(id) ON DELETE SET NULL,
|
||||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
||||||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
||||||
);
|
);
|
||||||
@@ -66,7 +68,10 @@ CREATE TABLE user_ebook_folders (
|
|||||||
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||||
folder_path VARCHAR(500) NOT NULL,
|
folder_path VARCHAR(500) NOT NULL,
|
||||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
||||||
UNIQUE(user_id, folder_path)
|
UNIQUE(user_id, folder_path),
|
||||||
|
CONSTRAINT admin_only_folder CHECK (EXISTS (
|
||||||
|
SELECT 1 FROM users WHERE id = user_id AND role = 'admin'
|
||||||
|
))
|
||||||
);
|
);
|
||||||
|
|
||||||
-- Create indexes for better query performance
|
-- Create indexes for better query performance
|
||||||
@@ -74,6 +79,7 @@ CREATE INDEX idx_users_email ON users(email);
|
|||||||
CREATE INDEX idx_users_username ON users(username);
|
CREATE INDEX idx_users_username ON users(username);
|
||||||
CREATE INDEX idx_ebooks_title ON ebooks(title);
|
CREATE INDEX idx_ebooks_title ON ebooks(title);
|
||||||
CREATE INDEX idx_ebooks_author ON ebooks(author);
|
CREATE INDEX idx_ebooks_author ON ebooks(author);
|
||||||
|
CREATE INDEX idx_ebooks_added_by_admin_id ON ebooks(added_by_admin_id);
|
||||||
CREATE INDEX idx_reading_progress_ebook_id ON reading_progress(ebook_id);
|
CREATE INDEX idx_reading_progress_ebook_id ON reading_progress(ebook_id);
|
||||||
CREATE INDEX idx_reading_progress_user_id ON reading_progress(user_id);
|
CREATE INDEX idx_reading_progress_user_id ON reading_progress(user_id);
|
||||||
CREATE INDEX idx_ebook_ratings_ebook_id ON ebook_ratings(ebook_id);
|
CREATE INDEX idx_ebook_ratings_ebook_id ON ebook_ratings(ebook_id);
|
||||||
@@ -82,3 +88,10 @@ CREATE INDEX idx_user_ebook_folders_user_id ON user_ebook_folders(user_id);
|
|||||||
|
|
||||||
-- Add comment explaining the rating system
|
-- Add comment explaining the rating system
|
||||||
COMMENT ON COLUMN ebook_ratings.rating IS 'Rating scale 1-10 (odd numbers = half-stars: 1,3,5,7,9 = 0.5,1.5,2.5,3.5,4.5 stars)';
|
COMMENT ON COLUMN ebook_ratings.rating IS 'Rating scale 1-10 (odd numbers = half-stars: 1,3,5,7,9 = 0.5,1.5,2.5,3.5,4.5 stars)';
|
||||||
|
|
||||||
|
-- Role System Notes:
|
||||||
|
-- - All users default to 'user' role
|
||||||
|
-- - Admin users can: add/edit/delete folders, scan ebooks, modify ebook metadata, delete ebooks
|
||||||
|
-- - Regular users can: view all ebooks, rate ebooks, track reading progress, manage their profile
|
||||||
|
-- - To create first admin: UPDATE users SET role = 'admin' WHERE email = 'your-admin-email';
|
||||||
|
-- - Only admins can manage folders and ebook metadata
|
||||||
@@ -12,6 +12,7 @@ type EbookRatings struct {
|
|||||||
ID pgtype.UUID `db:"id" json:"id"`
|
ID pgtype.UUID `db:"id" json:"id"`
|
||||||
EbookID pgtype.UUID `db:"ebook_id" json:"ebook_id"`
|
EbookID pgtype.UUID `db:"ebook_id" json:"ebook_id"`
|
||||||
UserID pgtype.UUID `db:"user_id" json:"user_id"`
|
UserID pgtype.UUID `db:"user_id" json:"user_id"`
|
||||||
|
// Rating scale 1-10 (odd numbers = half-stars: 1,3,5,7,9 = 0.5,1.5,2.5,3.5,4.5 stars)
|
||||||
Rating int32 `db:"rating" json:"rating"`
|
Rating int32 `db:"rating" json:"rating"`
|
||||||
CreatedAt pgtype.Timestamptz `db:"created_at" json:"created_at"`
|
CreatedAt pgtype.Timestamptz `db:"created_at" json:"created_at"`
|
||||||
UpdatedAt pgtype.Timestamptz `db:"updated_at" json:"updated_at"`
|
UpdatedAt pgtype.Timestamptz `db:"updated_at" json:"updated_at"`
|
||||||
@@ -27,8 +28,6 @@ type Ebooks struct {
|
|||||||
FileSize pgtype.Int8 `db:"file_size" json:"file_size"`
|
FileSize pgtype.Int8 `db:"file_size" json:"file_size"`
|
||||||
MimeType pgtype.Text `db:"mime_type" json:"mime_type"`
|
MimeType pgtype.Text `db:"mime_type" json:"mime_type"`
|
||||||
CoverImagePath pgtype.Text `db:"cover_image_path" json:"cover_image_path"`
|
CoverImagePath pgtype.Text `db:"cover_image_path" json:"cover_image_path"`
|
||||||
CreatedAt pgtype.Timestamptz `db:"created_at" json:"created_at"`
|
|
||||||
UpdatedAt pgtype.Timestamptz `db:"updated_at" json:"updated_at"`
|
|
||||||
Series pgtype.Text `db:"series" json:"series"`
|
Series pgtype.Text `db:"series" json:"series"`
|
||||||
SeriesNumber pgtype.Int4 `db:"series_number" json:"series_number"`
|
SeriesNumber pgtype.Int4 `db:"series_number" json:"series_number"`
|
||||||
Tags pgtype.Text `db:"tags" json:"tags"`
|
Tags pgtype.Text `db:"tags" json:"tags"`
|
||||||
@@ -36,6 +35,9 @@ type Ebooks struct {
|
|||||||
DatePublished pgtype.Date `db:"date_published" json:"date_published"`
|
DatePublished pgtype.Date `db:"date_published" json:"date_published"`
|
||||||
Publisher pgtype.Text `db:"publisher" json:"publisher"`
|
Publisher pgtype.Text `db:"publisher" json:"publisher"`
|
||||||
Contributors pgtype.Text `db:"contributors" json:"contributors"`
|
Contributors pgtype.Text `db:"contributors" json:"contributors"`
|
||||||
|
AddedByAdminID pgtype.UUID `db:"added_by_admin_id" json:"added_by_admin_id"`
|
||||||
|
CreatedAt pgtype.Timestamptz `db:"created_at" json:"created_at"`
|
||||||
|
UpdatedAt pgtype.Timestamptz `db:"updated_at" json:"updated_at"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ReadingProgress struct {
|
type ReadingProgress struct {
|
||||||
@@ -59,11 +61,12 @@ type Users struct {
|
|||||||
Email string `db:"email" json:"email"`
|
Email string `db:"email" json:"email"`
|
||||||
Username string `db:"username" json:"username"`
|
Username string `db:"username" json:"username"`
|
||||||
PasswordHash string `db:"password_hash" json:"password_hash"`
|
PasswordHash string `db:"password_hash" json:"password_hash"`
|
||||||
Theme pgtype.Text `db:"theme" json:"theme"`
|
|
||||||
CreatedAt pgtype.Timestamptz `db:"created_at" json:"created_at"`
|
|
||||||
UpdatedAt pgtype.Timestamptz `db:"updated_at" json:"updated_at"`
|
|
||||||
ScanFrequencyMinutes pgtype.Int4 `db:"scan_frequency_minutes" json:"scan_frequency_minutes"`
|
|
||||||
AutoScanEnabled pgtype.Bool `db:"auto_scan_enabled" json:"auto_scan_enabled"`
|
|
||||||
FirstName pgtype.Text `db:"first_name" json:"first_name"`
|
FirstName pgtype.Text `db:"first_name" json:"first_name"`
|
||||||
LastName pgtype.Text `db:"last_name" json:"last_name"`
|
LastName pgtype.Text `db:"last_name" json:"last_name"`
|
||||||
|
Role string `db:"role" json:"role"`
|
||||||
|
Theme pgtype.Text `db:"theme" json:"theme"`
|
||||||
|
ScanFrequencyMinutes pgtype.Int4 `db:"scan_frequency_minutes" json:"scan_frequency_minutes"`
|
||||||
|
AutoScanEnabled pgtype.Bool `db:"auto_scan_enabled" json:"auto_scan_enabled"`
|
||||||
|
CreatedAt pgtype.Timestamptz `db:"created_at" json:"created_at"`
|
||||||
|
UpdatedAt pgtype.Timestamptz `db:"updated_at" json:"updated_at"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,9 +33,9 @@ func (q *Queries) AddUserEbookFolder(ctx context.Context, arg AddUserEbookFolder
|
|||||||
}
|
}
|
||||||
|
|
||||||
const CreateEbook = `-- name: CreateEbook :one
|
const CreateEbook = `-- name: CreateEbook :one
|
||||||
INSERT INTO ebooks (title, author, isbn, description, file_path, file_size, mime_type, cover_image_path, series, series_number, tags, asin, date_published, publisher, contributors)
|
INSERT INTO ebooks (title, author, isbn, description, file_path, file_size, mime_type, cover_image_path, series, series_number, tags, asin, date_published, publisher, contributors, added_by_admin_id)
|
||||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15)
|
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16)
|
||||||
RETURNING id, title, author, isbn, description, file_path, file_size, mime_type, cover_image_path, created_at, updated_at, series, series_number, tags, asin, date_published, publisher, contributors
|
RETURNING id, title, author, isbn, description, file_path, file_size, mime_type, cover_image_path, series, series_number, tags, asin, date_published, publisher, contributors, added_by_admin_id, created_at, updated_at
|
||||||
`
|
`
|
||||||
|
|
||||||
type CreateEbookParams struct {
|
type CreateEbookParams struct {
|
||||||
@@ -54,6 +54,7 @@ type CreateEbookParams struct {
|
|||||||
DatePublished pgtype.Date `db:"date_published" json:"date_published"`
|
DatePublished pgtype.Date `db:"date_published" json:"date_published"`
|
||||||
Publisher pgtype.Text `db:"publisher" json:"publisher"`
|
Publisher pgtype.Text `db:"publisher" json:"publisher"`
|
||||||
Contributors pgtype.Text `db:"contributors" json:"contributors"`
|
Contributors pgtype.Text `db:"contributors" json:"contributors"`
|
||||||
|
AddedByAdminID pgtype.UUID `db:"added_by_admin_id" json:"added_by_admin_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *Queries) CreateEbook(ctx context.Context, arg CreateEbookParams) (Ebooks, error) {
|
func (q *Queries) CreateEbook(ctx context.Context, arg CreateEbookParams) (Ebooks, error) {
|
||||||
@@ -73,6 +74,7 @@ func (q *Queries) CreateEbook(ctx context.Context, arg CreateEbookParams) (Ebook
|
|||||||
arg.DatePublished,
|
arg.DatePublished,
|
||||||
arg.Publisher,
|
arg.Publisher,
|
||||||
arg.Contributors,
|
arg.Contributors,
|
||||||
|
arg.AddedByAdminID,
|
||||||
)
|
)
|
||||||
var i Ebooks
|
var i Ebooks
|
||||||
err := row.Scan(
|
err := row.Scan(
|
||||||
@@ -85,8 +87,6 @@ func (q *Queries) CreateEbook(ctx context.Context, arg CreateEbookParams) (Ebook
|
|||||||
&i.FileSize,
|
&i.FileSize,
|
||||||
&i.MimeType,
|
&i.MimeType,
|
||||||
&i.CoverImagePath,
|
&i.CoverImagePath,
|
||||||
&i.CreatedAt,
|
|
||||||
&i.UpdatedAt,
|
|
||||||
&i.Series,
|
&i.Series,
|
||||||
&i.SeriesNumber,
|
&i.SeriesNumber,
|
||||||
&i.Tags,
|
&i.Tags,
|
||||||
@@ -94,6 +94,9 @@ func (q *Queries) CreateEbook(ctx context.Context, arg CreateEbookParams) (Ebook
|
|||||||
&i.DatePublished,
|
&i.DatePublished,
|
||||||
&i.Publisher,
|
&i.Publisher,
|
||||||
&i.Contributors,
|
&i.Contributors,
|
||||||
|
&i.AddedByAdminID,
|
||||||
|
&i.CreatedAt,
|
||||||
|
&i.UpdatedAt,
|
||||||
)
|
)
|
||||||
return i, err
|
return i, err
|
||||||
}
|
}
|
||||||
@@ -131,7 +134,7 @@ func (q *Queries) CreateEbookRating(ctx context.Context, arg CreateEbookRatingPa
|
|||||||
const CreateUser = `-- name: CreateUser :one
|
const CreateUser = `-- name: CreateUser :one
|
||||||
INSERT INTO users (email, username, password_hash, first_name, last_name, theme)
|
INSERT INTO users (email, username, password_hash, first_name, last_name, theme)
|
||||||
VALUES ($1, $2, $3, $4, $5, $6)
|
VALUES ($1, $2, $3, $4, $5, $6)
|
||||||
RETURNING id, email, username, theme, first_name, last_name, created_at, updated_at
|
RETURNING id, email, username, theme, first_name, last_name, role, created_at, updated_at
|
||||||
`
|
`
|
||||||
|
|
||||||
type CreateUserParams struct {
|
type CreateUserParams struct {
|
||||||
@@ -150,6 +153,7 @@ type CreateUserRow struct {
|
|||||||
Theme pgtype.Text `db:"theme" json:"theme"`
|
Theme pgtype.Text `db:"theme" json:"theme"`
|
||||||
FirstName pgtype.Text `db:"first_name" json:"first_name"`
|
FirstName pgtype.Text `db:"first_name" json:"first_name"`
|
||||||
LastName pgtype.Text `db:"last_name" json:"last_name"`
|
LastName pgtype.Text `db:"last_name" json:"last_name"`
|
||||||
|
Role string `db:"role" json:"role"`
|
||||||
CreatedAt pgtype.Timestamptz `db:"created_at" json:"created_at"`
|
CreatedAt pgtype.Timestamptz `db:"created_at" json:"created_at"`
|
||||||
UpdatedAt pgtype.Timestamptz `db:"updated_at" json:"updated_at"`
|
UpdatedAt pgtype.Timestamptz `db:"updated_at" json:"updated_at"`
|
||||||
}
|
}
|
||||||
@@ -171,6 +175,7 @@ func (q *Queries) CreateUser(ctx context.Context, arg CreateUserParams) (CreateU
|
|||||||
&i.Theme,
|
&i.Theme,
|
||||||
&i.FirstName,
|
&i.FirstName,
|
||||||
&i.LastName,
|
&i.LastName,
|
||||||
|
&i.Role,
|
||||||
&i.CreatedAt,
|
&i.CreatedAt,
|
||||||
&i.UpdatedAt,
|
&i.UpdatedAt,
|
||||||
)
|
)
|
||||||
@@ -245,7 +250,7 @@ func (q *Queries) DeleteUserEbookFolder(ctx context.Context, arg DeleteUserEbook
|
|||||||
}
|
}
|
||||||
|
|
||||||
const GetEbook = `-- name: GetEbook :one
|
const GetEbook = `-- name: GetEbook :one
|
||||||
SELECT id, title, author, isbn, description, file_path, file_size, mime_type, cover_image_path, created_at, updated_at, series, series_number, tags, asin, date_published, publisher, contributors FROM ebooks WHERE id = $1
|
SELECT id, title, author, isbn, description, file_path, file_size, mime_type, cover_image_path, series, series_number, tags, asin, date_published, publisher, contributors, added_by_admin_id, created_at, updated_at FROM ebooks WHERE id = $1
|
||||||
`
|
`
|
||||||
|
|
||||||
func (q *Queries) GetEbook(ctx context.Context, id pgtype.UUID) (Ebooks, error) {
|
func (q *Queries) GetEbook(ctx context.Context, id pgtype.UUID) (Ebooks, error) {
|
||||||
@@ -261,8 +266,6 @@ func (q *Queries) GetEbook(ctx context.Context, id pgtype.UUID) (Ebooks, error)
|
|||||||
&i.FileSize,
|
&i.FileSize,
|
||||||
&i.MimeType,
|
&i.MimeType,
|
||||||
&i.CoverImagePath,
|
&i.CoverImagePath,
|
||||||
&i.CreatedAt,
|
|
||||||
&i.UpdatedAt,
|
|
||||||
&i.Series,
|
&i.Series,
|
||||||
&i.SeriesNumber,
|
&i.SeriesNumber,
|
||||||
&i.Tags,
|
&i.Tags,
|
||||||
@@ -270,12 +273,15 @@ func (q *Queries) GetEbook(ctx context.Context, id pgtype.UUID) (Ebooks, error)
|
|||||||
&i.DatePublished,
|
&i.DatePublished,
|
||||||
&i.Publisher,
|
&i.Publisher,
|
||||||
&i.Contributors,
|
&i.Contributors,
|
||||||
|
&i.AddedByAdminID,
|
||||||
|
&i.CreatedAt,
|
||||||
|
&i.UpdatedAt,
|
||||||
)
|
)
|
||||||
return i, err
|
return i, err
|
||||||
}
|
}
|
||||||
|
|
||||||
const GetEbookByFilePath = `-- name: GetEbookByFilePath :one
|
const GetEbookByFilePath = `-- name: GetEbookByFilePath :one
|
||||||
SELECT id, title, author, isbn, description, file_path, file_size, mime_type, cover_image_path, created_at, updated_at, series, series_number, tags, asin, date_published, publisher, contributors FROM ebooks WHERE file_path = $1
|
SELECT id, title, author, isbn, description, file_path, file_size, mime_type, cover_image_path, series, series_number, tags, asin, date_published, publisher, contributors, added_by_admin_id, created_at, updated_at FROM ebooks WHERE file_path = $1
|
||||||
`
|
`
|
||||||
|
|
||||||
func (q *Queries) GetEbookByFilePath(ctx context.Context, filePath string) (Ebooks, error) {
|
func (q *Queries) GetEbookByFilePath(ctx context.Context, filePath string) (Ebooks, error) {
|
||||||
@@ -291,8 +297,6 @@ func (q *Queries) GetEbookByFilePath(ctx context.Context, filePath string) (Eboo
|
|||||||
&i.FileSize,
|
&i.FileSize,
|
||||||
&i.MimeType,
|
&i.MimeType,
|
||||||
&i.CoverImagePath,
|
&i.CoverImagePath,
|
||||||
&i.CreatedAt,
|
|
||||||
&i.UpdatedAt,
|
|
||||||
&i.Series,
|
&i.Series,
|
||||||
&i.SeriesNumber,
|
&i.SeriesNumber,
|
||||||
&i.Tags,
|
&i.Tags,
|
||||||
@@ -300,6 +304,9 @@ func (q *Queries) GetEbookByFilePath(ctx context.Context, filePath string) (Eboo
|
|||||||
&i.DatePublished,
|
&i.DatePublished,
|
||||||
&i.Publisher,
|
&i.Publisher,
|
||||||
&i.Contributors,
|
&i.Contributors,
|
||||||
|
&i.AddedByAdminID,
|
||||||
|
&i.CreatedAt,
|
||||||
|
&i.UpdatedAt,
|
||||||
)
|
)
|
||||||
return i, err
|
return i, err
|
||||||
}
|
}
|
||||||
@@ -413,7 +420,7 @@ func (q *Queries) GetScanSettings(ctx context.Context, id pgtype.UUID) (GetScanS
|
|||||||
}
|
}
|
||||||
|
|
||||||
const GetUser = `-- name: GetUser :one
|
const GetUser = `-- name: GetUser :one
|
||||||
SELECT id, email, username, theme, first_name, last_name, created_at, updated_at FROM users WHERE id = $1
|
SELECT id, email, username, theme, first_name, last_name, role, created_at, updated_at FROM users WHERE id = $1
|
||||||
`
|
`
|
||||||
|
|
||||||
type GetUserRow struct {
|
type GetUserRow struct {
|
||||||
@@ -423,6 +430,7 @@ type GetUserRow struct {
|
|||||||
Theme pgtype.Text `db:"theme" json:"theme"`
|
Theme pgtype.Text `db:"theme" json:"theme"`
|
||||||
FirstName pgtype.Text `db:"first_name" json:"first_name"`
|
FirstName pgtype.Text `db:"first_name" json:"first_name"`
|
||||||
LastName pgtype.Text `db:"last_name" json:"last_name"`
|
LastName pgtype.Text `db:"last_name" json:"last_name"`
|
||||||
|
Role string `db:"role" json:"role"`
|
||||||
CreatedAt pgtype.Timestamptz `db:"created_at" json:"created_at"`
|
CreatedAt pgtype.Timestamptz `db:"created_at" json:"created_at"`
|
||||||
UpdatedAt pgtype.Timestamptz `db:"updated_at" json:"updated_at"`
|
UpdatedAt pgtype.Timestamptz `db:"updated_at" json:"updated_at"`
|
||||||
}
|
}
|
||||||
@@ -437,6 +445,7 @@ func (q *Queries) GetUser(ctx context.Context, id pgtype.UUID) (GetUserRow, erro
|
|||||||
&i.Theme,
|
&i.Theme,
|
||||||
&i.FirstName,
|
&i.FirstName,
|
||||||
&i.LastName,
|
&i.LastName,
|
||||||
|
&i.Role,
|
||||||
&i.CreatedAt,
|
&i.CreatedAt,
|
||||||
&i.UpdatedAt,
|
&i.UpdatedAt,
|
||||||
)
|
)
|
||||||
@@ -444,7 +453,7 @@ func (q *Queries) GetUser(ctx context.Context, id pgtype.UUID) (GetUserRow, erro
|
|||||||
}
|
}
|
||||||
|
|
||||||
const GetUserByEmail = `-- name: GetUserByEmail :one
|
const GetUserByEmail = `-- name: GetUserByEmail :one
|
||||||
SELECT id, email, username, theme, first_name, last_name, created_at, updated_at FROM users WHERE email = $1
|
SELECT id, email, username, theme, first_name, last_name, role, created_at, updated_at FROM users WHERE email = $1
|
||||||
`
|
`
|
||||||
|
|
||||||
type GetUserByEmailRow struct {
|
type GetUserByEmailRow struct {
|
||||||
@@ -454,6 +463,7 @@ type GetUserByEmailRow struct {
|
|||||||
Theme pgtype.Text `db:"theme" json:"theme"`
|
Theme pgtype.Text `db:"theme" json:"theme"`
|
||||||
FirstName pgtype.Text `db:"first_name" json:"first_name"`
|
FirstName pgtype.Text `db:"first_name" json:"first_name"`
|
||||||
LastName pgtype.Text `db:"last_name" json:"last_name"`
|
LastName pgtype.Text `db:"last_name" json:"last_name"`
|
||||||
|
Role string `db:"role" json:"role"`
|
||||||
CreatedAt pgtype.Timestamptz `db:"created_at" json:"created_at"`
|
CreatedAt pgtype.Timestamptz `db:"created_at" json:"created_at"`
|
||||||
UpdatedAt pgtype.Timestamptz `db:"updated_at" json:"updated_at"`
|
UpdatedAt pgtype.Timestamptz `db:"updated_at" json:"updated_at"`
|
||||||
}
|
}
|
||||||
@@ -468,6 +478,7 @@ func (q *Queries) GetUserByEmail(ctx context.Context, email string) (GetUserByEm
|
|||||||
&i.Theme,
|
&i.Theme,
|
||||||
&i.FirstName,
|
&i.FirstName,
|
||||||
&i.LastName,
|
&i.LastName,
|
||||||
|
&i.Role,
|
||||||
&i.CreatedAt,
|
&i.CreatedAt,
|
||||||
&i.UpdatedAt,
|
&i.UpdatedAt,
|
||||||
)
|
)
|
||||||
@@ -475,7 +486,7 @@ func (q *Queries) GetUserByEmail(ctx context.Context, email string) (GetUserByEm
|
|||||||
}
|
}
|
||||||
|
|
||||||
const GetUserByEmailOrUsername = `-- name: GetUserByEmailOrUsername :one
|
const GetUserByEmailOrUsername = `-- name: GetUserByEmailOrUsername :one
|
||||||
SELECT id, email, username, theme, first_name, last_name, created_at, updated_at FROM users WHERE email = $1 OR username = $1
|
SELECT id, email, username, theme, first_name, last_name, role, created_at, updated_at FROM users WHERE email = $1 OR username = $1
|
||||||
`
|
`
|
||||||
|
|
||||||
type GetUserByEmailOrUsernameRow struct {
|
type GetUserByEmailOrUsernameRow struct {
|
||||||
@@ -485,6 +496,7 @@ type GetUserByEmailOrUsernameRow struct {
|
|||||||
Theme pgtype.Text `db:"theme" json:"theme"`
|
Theme pgtype.Text `db:"theme" json:"theme"`
|
||||||
FirstName pgtype.Text `db:"first_name" json:"first_name"`
|
FirstName pgtype.Text `db:"first_name" json:"first_name"`
|
||||||
LastName pgtype.Text `db:"last_name" json:"last_name"`
|
LastName pgtype.Text `db:"last_name" json:"last_name"`
|
||||||
|
Role string `db:"role" json:"role"`
|
||||||
CreatedAt pgtype.Timestamptz `db:"created_at" json:"created_at"`
|
CreatedAt pgtype.Timestamptz `db:"created_at" json:"created_at"`
|
||||||
UpdatedAt pgtype.Timestamptz `db:"updated_at" json:"updated_at"`
|
UpdatedAt pgtype.Timestamptz `db:"updated_at" json:"updated_at"`
|
||||||
}
|
}
|
||||||
@@ -499,6 +511,7 @@ func (q *Queries) GetUserByEmailOrUsername(ctx context.Context, email string) (G
|
|||||||
&i.Theme,
|
&i.Theme,
|
||||||
&i.FirstName,
|
&i.FirstName,
|
||||||
&i.LastName,
|
&i.LastName,
|
||||||
|
&i.Role,
|
||||||
&i.CreatedAt,
|
&i.CreatedAt,
|
||||||
&i.UpdatedAt,
|
&i.UpdatedAt,
|
||||||
)
|
)
|
||||||
@@ -506,7 +519,7 @@ func (q *Queries) GetUserByEmailOrUsername(ctx context.Context, email string) (G
|
|||||||
}
|
}
|
||||||
|
|
||||||
const GetUserByUsername = `-- name: GetUserByUsername :one
|
const GetUserByUsername = `-- name: GetUserByUsername :one
|
||||||
SELECT id, email, username, theme, first_name, last_name, created_at, updated_at FROM users WHERE username = $1
|
SELECT id, email, username, theme, first_name, last_name, role, created_at, updated_at FROM users WHERE username = $1
|
||||||
`
|
`
|
||||||
|
|
||||||
type GetUserByUsernameRow struct {
|
type GetUserByUsernameRow struct {
|
||||||
@@ -516,6 +529,7 @@ type GetUserByUsernameRow struct {
|
|||||||
Theme pgtype.Text `db:"theme" json:"theme"`
|
Theme pgtype.Text `db:"theme" json:"theme"`
|
||||||
FirstName pgtype.Text `db:"first_name" json:"first_name"`
|
FirstName pgtype.Text `db:"first_name" json:"first_name"`
|
||||||
LastName pgtype.Text `db:"last_name" json:"last_name"`
|
LastName pgtype.Text `db:"last_name" json:"last_name"`
|
||||||
|
Role string `db:"role" json:"role"`
|
||||||
CreatedAt pgtype.Timestamptz `db:"created_at" json:"created_at"`
|
CreatedAt pgtype.Timestamptz `db:"created_at" json:"created_at"`
|
||||||
UpdatedAt pgtype.Timestamptz `db:"updated_at" json:"updated_at"`
|
UpdatedAt pgtype.Timestamptz `db:"updated_at" json:"updated_at"`
|
||||||
}
|
}
|
||||||
@@ -530,6 +544,7 @@ func (q *Queries) GetUserByUsername(ctx context.Context, username string) (GetUs
|
|||||||
&i.Theme,
|
&i.Theme,
|
||||||
&i.FirstName,
|
&i.FirstName,
|
||||||
&i.LastName,
|
&i.LastName,
|
||||||
|
&i.Role,
|
||||||
&i.CreatedAt,
|
&i.CreatedAt,
|
||||||
&i.UpdatedAt,
|
&i.UpdatedAt,
|
||||||
)
|
)
|
||||||
@@ -566,7 +581,7 @@ func (q *Queries) GetUserEbookFolders(ctx context.Context, userID pgtype.UUID) (
|
|||||||
}
|
}
|
||||||
|
|
||||||
const GetUserForLogin = `-- name: GetUserForLogin :one
|
const GetUserForLogin = `-- name: GetUserForLogin :one
|
||||||
SELECT id, email, username, password_hash, theme, first_name, last_name, created_at, updated_at FROM users WHERE email = $1 OR username = $1
|
SELECT id, email, username, password_hash, theme, first_name, last_name, role, created_at, updated_at FROM users WHERE email = $1 OR username = $1
|
||||||
`
|
`
|
||||||
|
|
||||||
type GetUserForLoginRow struct {
|
type GetUserForLoginRow struct {
|
||||||
@@ -577,6 +592,7 @@ type GetUserForLoginRow struct {
|
|||||||
Theme pgtype.Text `db:"theme" json:"theme"`
|
Theme pgtype.Text `db:"theme" json:"theme"`
|
||||||
FirstName pgtype.Text `db:"first_name" json:"first_name"`
|
FirstName pgtype.Text `db:"first_name" json:"first_name"`
|
||||||
LastName pgtype.Text `db:"last_name" json:"last_name"`
|
LastName pgtype.Text `db:"last_name" json:"last_name"`
|
||||||
|
Role string `db:"role" json:"role"`
|
||||||
CreatedAt pgtype.Timestamptz `db:"created_at" json:"created_at"`
|
CreatedAt pgtype.Timestamptz `db:"created_at" json:"created_at"`
|
||||||
UpdatedAt pgtype.Timestamptz `db:"updated_at" json:"updated_at"`
|
UpdatedAt pgtype.Timestamptz `db:"updated_at" json:"updated_at"`
|
||||||
}
|
}
|
||||||
@@ -592,6 +608,7 @@ func (q *Queries) GetUserForLogin(ctx context.Context, email string) (GetUserFor
|
|||||||
&i.Theme,
|
&i.Theme,
|
||||||
&i.FirstName,
|
&i.FirstName,
|
||||||
&i.LastName,
|
&i.LastName,
|
||||||
|
&i.Role,
|
||||||
&i.CreatedAt,
|
&i.CreatedAt,
|
||||||
&i.UpdatedAt,
|
&i.UpdatedAt,
|
||||||
)
|
)
|
||||||
@@ -610,7 +627,7 @@ func (q *Queries) GetUserPasswordHash(ctx context.Context, id pgtype.UUID) (stri
|
|||||||
}
|
}
|
||||||
|
|
||||||
const ListEbooks = `-- name: ListEbooks :many
|
const ListEbooks = `-- name: ListEbooks :many
|
||||||
SELECT id, title, author, isbn, description, file_path, file_size, mime_type, cover_image_path, created_at, updated_at, series, series_number, tags, asin, date_published, publisher, contributors FROM ebooks ORDER BY created_at DESC LIMIT $1 OFFSET $2
|
SELECT id, title, author, isbn, description, file_path, file_size, mime_type, cover_image_path, series, series_number, tags, asin, date_published, publisher, contributors, added_by_admin_id, created_at, updated_at FROM ebooks ORDER BY created_at DESC LIMIT $1 OFFSET $2
|
||||||
`
|
`
|
||||||
|
|
||||||
type ListEbooksParams struct {
|
type ListEbooksParams struct {
|
||||||
@@ -637,8 +654,6 @@ func (q *Queries) ListEbooks(ctx context.Context, arg ListEbooksParams) ([]Ebook
|
|||||||
&i.FileSize,
|
&i.FileSize,
|
||||||
&i.MimeType,
|
&i.MimeType,
|
||||||
&i.CoverImagePath,
|
&i.CoverImagePath,
|
||||||
&i.CreatedAt,
|
|
||||||
&i.UpdatedAt,
|
|
||||||
&i.Series,
|
&i.Series,
|
||||||
&i.SeriesNumber,
|
&i.SeriesNumber,
|
||||||
&i.Tags,
|
&i.Tags,
|
||||||
@@ -646,6 +661,9 @@ func (q *Queries) ListEbooks(ctx context.Context, arg ListEbooksParams) ([]Ebook
|
|||||||
&i.DatePublished,
|
&i.DatePublished,
|
||||||
&i.Publisher,
|
&i.Publisher,
|
||||||
&i.Contributors,
|
&i.Contributors,
|
||||||
|
&i.AddedByAdminID,
|
||||||
|
&i.CreatedAt,
|
||||||
|
&i.UpdatedAt,
|
||||||
); err != nil {
|
); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -658,7 +676,7 @@ func (q *Queries) ListEbooks(ctx context.Context, arg ListEbooksParams) ([]Ebook
|
|||||||
}
|
}
|
||||||
|
|
||||||
const ListUsers = `-- name: ListUsers :many
|
const ListUsers = `-- name: ListUsers :many
|
||||||
SELECT id, email, username, theme, first_name, last_name, created_at, updated_at FROM users ORDER BY created_at DESC
|
SELECT id, email, username, theme, first_name, last_name, role, created_at, updated_at FROM users ORDER BY created_at DESC
|
||||||
`
|
`
|
||||||
|
|
||||||
type ListUsersRow struct {
|
type ListUsersRow struct {
|
||||||
@@ -668,6 +686,7 @@ type ListUsersRow struct {
|
|||||||
Theme pgtype.Text `db:"theme" json:"theme"`
|
Theme pgtype.Text `db:"theme" json:"theme"`
|
||||||
FirstName pgtype.Text `db:"first_name" json:"first_name"`
|
FirstName pgtype.Text `db:"first_name" json:"first_name"`
|
||||||
LastName pgtype.Text `db:"last_name" json:"last_name"`
|
LastName pgtype.Text `db:"last_name" json:"last_name"`
|
||||||
|
Role string `db:"role" json:"role"`
|
||||||
CreatedAt pgtype.Timestamptz `db:"created_at" json:"created_at"`
|
CreatedAt pgtype.Timestamptz `db:"created_at" json:"created_at"`
|
||||||
UpdatedAt pgtype.Timestamptz `db:"updated_at" json:"updated_at"`
|
UpdatedAt pgtype.Timestamptz `db:"updated_at" json:"updated_at"`
|
||||||
}
|
}
|
||||||
@@ -688,6 +707,7 @@ func (q *Queries) ListUsers(ctx context.Context) ([]ListUsersRow, error) {
|
|||||||
&i.Theme,
|
&i.Theme,
|
||||||
&i.FirstName,
|
&i.FirstName,
|
||||||
&i.LastName,
|
&i.LastName,
|
||||||
|
&i.Role,
|
||||||
&i.CreatedAt,
|
&i.CreatedAt,
|
||||||
&i.UpdatedAt,
|
&i.UpdatedAt,
|
||||||
); err != nil {
|
); err != nil {
|
||||||
@@ -717,7 +737,7 @@ UPDATE ebooks SET
|
|||||||
contributors = $13,
|
contributors = $13,
|
||||||
updated_at = NOW()
|
updated_at = NOW()
|
||||||
WHERE id = $1
|
WHERE id = $1
|
||||||
RETURNING id, title, author, isbn, description, file_path, file_size, mime_type, cover_image_path, created_at, updated_at, series, series_number, tags, asin, date_published, publisher, contributors
|
RETURNING id, title, author, isbn, description, file_path, file_size, mime_type, cover_image_path, series, series_number, tags, asin, date_published, publisher, contributors, added_by_admin_id, created_at, updated_at
|
||||||
`
|
`
|
||||||
|
|
||||||
type UpdateEbookParams struct {
|
type UpdateEbookParams struct {
|
||||||
@@ -763,8 +783,6 @@ func (q *Queries) UpdateEbook(ctx context.Context, arg UpdateEbookParams) (Ebook
|
|||||||
&i.FileSize,
|
&i.FileSize,
|
||||||
&i.MimeType,
|
&i.MimeType,
|
||||||
&i.CoverImagePath,
|
&i.CoverImagePath,
|
||||||
&i.CreatedAt,
|
|
||||||
&i.UpdatedAt,
|
|
||||||
&i.Series,
|
&i.Series,
|
||||||
&i.SeriesNumber,
|
&i.SeriesNumber,
|
||||||
&i.Tags,
|
&i.Tags,
|
||||||
@@ -772,6 +790,9 @@ func (q *Queries) UpdateEbook(ctx context.Context, arg UpdateEbookParams) (Ebook
|
|||||||
&i.DatePublished,
|
&i.DatePublished,
|
||||||
&i.Publisher,
|
&i.Publisher,
|
||||||
&i.Contributors,
|
&i.Contributors,
|
||||||
|
&i.AddedByAdminID,
|
||||||
|
&i.CreatedAt,
|
||||||
|
&i.UpdatedAt,
|
||||||
)
|
)
|
||||||
return i, err
|
return i, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,28 +1,28 @@
|
|||||||
-- name: CreateUser :one
|
-- name: CreateUser :one
|
||||||
INSERT INTO users (email, username, password_hash, first_name, last_name, theme)
|
INSERT INTO users (email, username, password_hash, first_name, last_name, theme)
|
||||||
VALUES ($1, $2, $3, $4, $5, $6)
|
VALUES ($1, $2, $3, $4, $5, $6)
|
||||||
RETURNING id, email, username, theme, first_name, last_name, created_at, updated_at;
|
RETURNING id, email, username, theme, first_name, last_name, role, created_at, updated_at;
|
||||||
|
|
||||||
-- name: GetUserByEmail :one
|
-- name: GetUserByEmail :one
|
||||||
SELECT id, email, username, theme, first_name, last_name, created_at, updated_at FROM users WHERE email = $1;
|
SELECT id, email, username, theme, first_name, last_name, role, created_at, updated_at FROM users WHERE email = $1;
|
||||||
|
|
||||||
-- name: GetUserByUsername :one
|
-- name: GetUserByUsername :one
|
||||||
SELECT id, email, username, theme, first_name, last_name, created_at, updated_at FROM users WHERE username = $1;
|
SELECT id, email, username, theme, first_name, last_name, role, created_at, updated_at FROM users WHERE username = $1;
|
||||||
|
|
||||||
-- name: GetUserByEmailOrUsername :one
|
-- name: GetUserByEmailOrUsername :one
|
||||||
SELECT id, email, username, theme, first_name, last_name, created_at, updated_at FROM users WHERE email = $1 OR username = $1;
|
SELECT id, email, username, theme, first_name, last_name, role, created_at, updated_at FROM users WHERE email = $1 OR username = $1;
|
||||||
|
|
||||||
-- name: GetUserForLogin :one
|
-- name: GetUserForLogin :one
|
||||||
SELECT id, email, username, password_hash, theme, first_name, last_name, created_at, updated_at FROM users WHERE email = $1 OR username = $1;
|
SELECT id, email, username, password_hash, theme, first_name, last_name, role, created_at, updated_at FROM users WHERE email = $1 OR username = $1;
|
||||||
|
|
||||||
-- name: GetUser :one
|
-- name: GetUser :one
|
||||||
SELECT id, email, username, theme, first_name, last_name, created_at, updated_at FROM users WHERE id = $1;
|
SELECT id, email, username, theme, first_name, last_name, role, created_at, updated_at FROM users WHERE id = $1;
|
||||||
|
|
||||||
-- name: GetUserPasswordHash :one
|
-- name: GetUserPasswordHash :one
|
||||||
SELECT password_hash FROM users WHERE id = $1;
|
SELECT password_hash FROM users WHERE id = $1;
|
||||||
|
|
||||||
-- name: ListUsers :many
|
-- name: ListUsers :many
|
||||||
SELECT id, email, username, theme, first_name, last_name, created_at, updated_at FROM users ORDER BY created_at DESC;
|
SELECT id, email, username, theme, first_name, last_name, role, created_at, updated_at FROM users ORDER BY created_at DESC;
|
||||||
|
|
||||||
-- name: GetEbook :one
|
-- name: GetEbook :one
|
||||||
SELECT * FROM ebooks WHERE id = $1;
|
SELECT * FROM ebooks WHERE id = $1;
|
||||||
@@ -31,8 +31,8 @@ SELECT * FROM ebooks WHERE id = $1;
|
|||||||
SELECT * FROM ebooks ORDER BY created_at DESC LIMIT $1 OFFSET $2;
|
SELECT * FROM ebooks ORDER BY created_at DESC LIMIT $1 OFFSET $2;
|
||||||
|
|
||||||
-- name: CreateEbook :one
|
-- name: CreateEbook :one
|
||||||
INSERT INTO ebooks (title, author, isbn, description, file_path, file_size, mime_type, cover_image_path, series, series_number, tags, asin, date_published, publisher, contributors)
|
INSERT INTO ebooks (title, author, isbn, description, file_path, file_size, mime_type, cover_image_path, series, series_number, tags, asin, date_published, publisher, contributors, added_by_admin_id)
|
||||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15)
|
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16)
|
||||||
RETURNING *;
|
RETURNING *;
|
||||||
|
|
||||||
-- name: UpdateEbook :one
|
-- name: UpdateEbook :one
|
||||||
|
|||||||
Reference in New Issue
Block a user