Merged in feature/eula.part1 (pull request #206)

eula support

* eula support

* docs
This commit is contained in:
Jay Brown
2026-01-22 18:17:27 +00:00
parent c10fa98d0a
commit 63c12a2f44
38 changed files with 15646 additions and 230 deletions
+582
View File
@@ -0,0 +1,582 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.27.0
// source: eula.sql
package repository
import (
"context"
"github.com/google/uuid"
"github.com/jackc/pgx/v5/pgtype"
)
const clearCurrentEulaVersions = `-- name: ClearCurrentEulaVersions :exec
UPDATE eulaVersions
SET isCurrent = FALSE
WHERE isCurrent = TRUE
`
// Clears the isCurrent flag from all versions (does not clear activatedAt/By for audit trail)
//
// UPDATE eulaVersions
// SET isCurrent = FALSE
// WHERE isCurrent = TRUE
func (q *Queries) ClearCurrentEulaVersions(ctx context.Context) error {
_, err := q.db.Exec(ctx, clearCurrentEulaVersions)
return err
}
const countEulaAgreements = `-- name: CountEulaAgreements :one
SELECT COUNT(*) as total
FROM eulaAgreements a
WHERE ($1::uuid IS NULL OR a.eulaVersionId = $1::uuid)
AND ($2::text IS NULL OR a.cognitoSubjectId = $2::text)
`
type CountEulaAgreementsParams struct {
VersionID *uuid.UUID `db:"version_id"`
UserID *string `db:"user_id"`
}
// Counts agreements with optional filtering (matches ListEulaAgreements filters)
//
// SELECT COUNT(*) as total
// FROM eulaAgreements a
// WHERE ($1::uuid IS NULL OR a.eulaVersionId = $1::uuid)
// AND ($2::text IS NULL OR a.cognitoSubjectId = $2::text)
func (q *Queries) CountEulaAgreements(ctx context.Context, arg *CountEulaAgreementsParams) (int64, error) {
row := q.db.QueryRow(ctx, countEulaAgreements, arg.VersionID, arg.UserID)
var total int64
err := row.Scan(&total)
return total, err
}
const countEulaAgreementsByVersion = `-- name: CountEulaAgreementsByVersion :one
SELECT COUNT(*) as count
FROM eulaAgreements
WHERE eulaVersionId = $1
`
// Counts how many users have agreed to a specific EULA version
//
// SELECT COUNT(*) as count
// FROM eulaAgreements
// WHERE eulaVersionId = $1
func (q *Queries) CountEulaAgreementsByVersion(ctx context.Context, eulaversionid uuid.UUID) (int64, error) {
row := q.db.QueryRow(ctx, countEulaAgreementsByVersion, eulaversionid)
var count int64
err := row.Scan(&count)
return count, err
}
const countEulaVersions = `-- name: CountEulaVersions :one
SELECT COUNT(*) as total
FROM eulaVersions
`
// Counts total number of EULA versions
//
// SELECT COUNT(*) as total
// FROM eulaVersions
func (q *Queries) CountEulaVersions(ctx context.Context) (int64, error) {
row := q.db.QueryRow(ctx, countEulaVersions)
var total int64
err := row.Scan(&total)
return total, err
}
const createEulaAgreement = `-- name: CreateEulaAgreement :one
INSERT INTO eulaAgreements (cognitoSubjectId, userEmail, eulaVersionId, agreedFromIp)
VALUES ($1, $2, $3, $4)
RETURNING id, cognitoSubjectId, userEmail, eulaVersionId, agreedAt, agreedFromIp
`
type CreateEulaAgreementParams struct {
Cognitosubjectid string `db:"cognitosubjectid"`
Useremail string `db:"useremail"`
Eulaversionid uuid.UUID `db:"eulaversionid"`
Agreedfromip string `db:"agreedfromip"`
}
// Records a user's agreement to an EULA version
//
// INSERT INTO eulaAgreements (cognitoSubjectId, userEmail, eulaVersionId, agreedFromIp)
// VALUES ($1, $2, $3, $4)
// RETURNING id, cognitoSubjectId, userEmail, eulaVersionId, agreedAt, agreedFromIp
func (q *Queries) CreateEulaAgreement(ctx context.Context, arg *CreateEulaAgreementParams) (*Eulaagreement, error) {
row := q.db.QueryRow(ctx, createEulaAgreement,
arg.Cognitosubjectid,
arg.Useremail,
arg.Eulaversionid,
arg.Agreedfromip,
)
var i Eulaagreement
err := row.Scan(
&i.ID,
&i.Cognitosubjectid,
&i.Useremail,
&i.Eulaversionid,
&i.Agreedat,
&i.Agreedfromip,
)
return &i, err
}
const createEulaVersion = `-- name: CreateEulaVersion :one
INSERT INTO eulaVersions (version, title, content, effectiveDate, createdBy)
VALUES ($1, $2, $3, $4, $5)
RETURNING id, version, title, content, effectiveDate, createdAt, createdBy, isCurrent, activatedAt, activatedBy
`
type CreateEulaVersionParams struct {
Version string `db:"version"`
Title string `db:"title"`
Content string `db:"content"`
Effectivedate pgtype.Timestamptz `db:"effectivedate"`
Createdby string `db:"createdby"`
}
// Creates a new EULA version
//
// INSERT INTO eulaVersions (version, title, content, effectiveDate, createdBy)
// VALUES ($1, $2, $3, $4, $5)
// RETURNING id, version, title, content, effectiveDate, createdAt, createdBy, isCurrent, activatedAt, activatedBy
func (q *Queries) CreateEulaVersion(ctx context.Context, arg *CreateEulaVersionParams) (*Eulaversion, error) {
row := q.db.QueryRow(ctx, createEulaVersion,
arg.Version,
arg.Title,
arg.Content,
arg.Effectivedate,
arg.Createdby,
)
var i Eulaversion
err := row.Scan(
&i.ID,
&i.Version,
&i.Title,
&i.Content,
&i.Effectivedate,
&i.Createdat,
&i.Createdby,
&i.Iscurrent,
&i.Activatedat,
&i.Activatedby,
)
return &i, err
}
const getCurrentEulaVersion = `-- name: GetCurrentEulaVersion :one
SELECT id, version, title, content, effectiveDate, createdAt, createdBy, isCurrent, activatedAt, activatedBy
FROM eulaVersions
WHERE isCurrent = TRUE
`
// Retrieves the current active EULA version
//
// SELECT id, version, title, content, effectiveDate, createdAt, createdBy, isCurrent, activatedAt, activatedBy
// FROM eulaVersions
// WHERE isCurrent = TRUE
func (q *Queries) GetCurrentEulaVersion(ctx context.Context) (*Eulaversion, error) {
row := q.db.QueryRow(ctx, getCurrentEulaVersion)
var i Eulaversion
err := row.Scan(
&i.ID,
&i.Version,
&i.Title,
&i.Content,
&i.Effectivedate,
&i.Createdat,
&i.Createdby,
&i.Iscurrent,
&i.Activatedat,
&i.Activatedby,
)
return &i, err
}
const getEulaVersionById = `-- name: GetEulaVersionById :one
SELECT id, version, title, content, effectiveDate, createdAt, createdBy, isCurrent, activatedAt, activatedBy
FROM eulaVersions
WHERE id = $1
`
// Retrieves a specific EULA version by its ID
//
// SELECT id, version, title, content, effectiveDate, createdAt, createdBy, isCurrent, activatedAt, activatedBy
// FROM eulaVersions
// WHERE id = $1
func (q *Queries) GetEulaVersionById(ctx context.Context, id uuid.UUID) (*Eulaversion, error) {
row := q.db.QueryRow(ctx, getEulaVersionById, id)
var i Eulaversion
err := row.Scan(
&i.ID,
&i.Version,
&i.Title,
&i.Content,
&i.Effectivedate,
&i.Createdat,
&i.Createdby,
&i.Iscurrent,
&i.Activatedat,
&i.Activatedby,
)
return &i, err
}
const getUserCurrentEulaAgreement = `-- name: GetUserCurrentEulaAgreement :one
SELECT a.id, a.cognitoSubjectId, a.userEmail, a.eulaVersionId, a.agreedAt, a.agreedFromIp
FROM eulaAgreements a
JOIN eulaVersions v ON a.eulaVersionId = v.id
WHERE a.cognitoSubjectId = $1 AND v.isCurrent = TRUE
`
// Checks if a user has agreed to the current EULA version
//
// SELECT a.id, a.cognitoSubjectId, a.userEmail, a.eulaVersionId, a.agreedAt, a.agreedFromIp
// FROM eulaAgreements a
// JOIN eulaVersions v ON a.eulaVersionId = v.id
// WHERE a.cognitoSubjectId = $1 AND v.isCurrent = TRUE
func (q *Queries) GetUserCurrentEulaAgreement(ctx context.Context, cognitosubjectid string) (*Eulaagreement, error) {
row := q.db.QueryRow(ctx, getUserCurrentEulaAgreement, cognitosubjectid)
var i Eulaagreement
err := row.Scan(
&i.ID,
&i.Cognitosubjectid,
&i.Useremail,
&i.Eulaversionid,
&i.Agreedat,
&i.Agreedfromip,
)
return &i, err
}
const getUserEulaAgreement = `-- name: GetUserEulaAgreement :one
SELECT id, cognitoSubjectId, userEmail, eulaVersionId, agreedAt, agreedFromIp
FROM eulaAgreements
WHERE cognitoSubjectId = $1 AND eulaVersionId = $2
`
type GetUserEulaAgreementParams struct {
Cognitosubjectid string `db:"cognitosubjectid"`
Eulaversionid uuid.UUID `db:"eulaversionid"`
}
// Checks if a user has agreed to a specific EULA version
//
// SELECT id, cognitoSubjectId, userEmail, eulaVersionId, agreedAt, agreedFromIp
// FROM eulaAgreements
// WHERE cognitoSubjectId = $1 AND eulaVersionId = $2
func (q *Queries) GetUserEulaAgreement(ctx context.Context, arg *GetUserEulaAgreementParams) (*Eulaagreement, error) {
row := q.db.QueryRow(ctx, getUserEulaAgreement, arg.Cognitosubjectid, arg.Eulaversionid)
var i Eulaagreement
err := row.Scan(
&i.ID,
&i.Cognitosubjectid,
&i.Useremail,
&i.Eulaversionid,
&i.Agreedat,
&i.Agreedfromip,
)
return &i, err
}
const listAgreedUsersForVersion = `-- name: ListAgreedUsersForVersion :many
SELECT id, cognitoSubjectId, userEmail, eulaVersionId, agreedAt, agreedFromIp
FROM eulaAgreements
WHERE eulaVersionId = $1
ORDER BY agreedAt DESC
LIMIT $2 OFFSET $3
`
type ListAgreedUsersForVersionParams struct {
Eulaversionid uuid.UUID `db:"eulaversionid"`
Limit int64 `db:"limit"`
Offset int64 `db:"offset"`
}
// Lists all users who have agreed to a specific EULA version
//
// SELECT id, cognitoSubjectId, userEmail, eulaVersionId, agreedAt, agreedFromIp
// FROM eulaAgreements
// WHERE eulaVersionId = $1
// ORDER BY agreedAt DESC
// LIMIT $2 OFFSET $3
func (q *Queries) ListAgreedUsersForVersion(ctx context.Context, arg *ListAgreedUsersForVersionParams) ([]*Eulaagreement, error) {
rows, err := q.db.Query(ctx, listAgreedUsersForVersion, arg.Eulaversionid, arg.Limit, arg.Offset)
if err != nil {
return nil, err
}
defer rows.Close()
items := []*Eulaagreement{}
for rows.Next() {
var i Eulaagreement
if err := rows.Scan(
&i.ID,
&i.Cognitosubjectid,
&i.Useremail,
&i.Eulaversionid,
&i.Agreedat,
&i.Agreedfromip,
); err != nil {
return nil, err
}
items = append(items, &i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listEulaAgreements = `-- name: ListEulaAgreements :many
SELECT a.id, a.cognitoSubjectId, a.userEmail, a.eulaVersionId, a.agreedAt, a.agreedFromIp,
v.version as eulaVersionString
FROM eulaAgreements a
JOIN eulaVersions v ON a.eulaVersionId = v.id
WHERE ($3::uuid IS NULL OR a.eulaVersionId = $3::uuid)
AND ($4::text IS NULL OR a.cognitoSubjectId = $4::text)
ORDER BY a.agreedAt DESC
LIMIT $1 OFFSET $2
`
type ListEulaAgreementsParams struct {
Limit int64 `db:"limit"`
Offset int64 `db:"offset"`
VersionID *uuid.UUID `db:"version_id"`
UserID *string `db:"user_id"`
}
type ListEulaAgreementsRow struct {
ID uuid.UUID `db:"id"`
Cognitosubjectid string `db:"cognitosubjectid"`
Useremail string `db:"useremail"`
Eulaversionid uuid.UUID `db:"eulaversionid"`
Agreedat pgtype.Timestamptz `db:"agreedat"`
Agreedfromip string `db:"agreedfromip"`
Eulaversionstring string `db:"eulaversionstring"`
}
// Lists agreements with optional filtering by version_id or user_id
// Pass NULL for filters to skip them
//
// SELECT a.id, a.cognitoSubjectId, a.userEmail, a.eulaVersionId, a.agreedAt, a.agreedFromIp,
// v.version as eulaVersionString
// FROM eulaAgreements a
// JOIN eulaVersions v ON a.eulaVersionId = v.id
// WHERE ($3::uuid IS NULL OR a.eulaVersionId = $3::uuid)
// AND ($4::text IS NULL OR a.cognitoSubjectId = $4::text)
// ORDER BY a.agreedAt DESC
// LIMIT $1 OFFSET $2
func (q *Queries) ListEulaAgreements(ctx context.Context, arg *ListEulaAgreementsParams) ([]*ListEulaAgreementsRow, error) {
rows, err := q.db.Query(ctx, listEulaAgreements,
arg.Limit,
arg.Offset,
arg.VersionID,
arg.UserID,
)
if err != nil {
return nil, err
}
defer rows.Close()
items := []*ListEulaAgreementsRow{}
for rows.Next() {
var i ListEulaAgreementsRow
if err := rows.Scan(
&i.ID,
&i.Cognitosubjectid,
&i.Useremail,
&i.Eulaversionid,
&i.Agreedat,
&i.Agreedfromip,
&i.Eulaversionstring,
); err != nil {
return nil, err
}
items = append(items, &i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listEulaAgreementsByUser = `-- name: ListEulaAgreementsByUser :many
SELECT a.id, a.cognitoSubjectId, a.userEmail, a.eulaVersionId, a.agreedAt, a.agreedFromIp,
v.version as eulaVersionString, v.title as eulaVersionTitle
FROM eulaAgreements a
JOIN eulaVersions v ON a.eulaVersionId = v.id
WHERE a.cognitoSubjectId = $1
ORDER BY a.agreedAt DESC
`
type ListEulaAgreementsByUserRow struct {
ID uuid.UUID `db:"id"`
Cognitosubjectid string `db:"cognitosubjectid"`
Useremail string `db:"useremail"`
Eulaversionid uuid.UUID `db:"eulaversionid"`
Agreedat pgtype.Timestamptz `db:"agreedat"`
Agreedfromip string `db:"agreedfromip"`
Eulaversionstring string `db:"eulaversionstring"`
Eulaversiontitle string `db:"eulaversiontitle"`
}
// Gets all EULA versions a specific user has agreed to (user's complete history)
//
// SELECT a.id, a.cognitoSubjectId, a.userEmail, a.eulaVersionId, a.agreedAt, a.agreedFromIp,
// v.version as eulaVersionString, v.title as eulaVersionTitle
// FROM eulaAgreements a
// JOIN eulaVersions v ON a.eulaVersionId = v.id
// WHERE a.cognitoSubjectId = $1
// ORDER BY a.agreedAt DESC
func (q *Queries) ListEulaAgreementsByUser(ctx context.Context, cognitosubjectid string) ([]*ListEulaAgreementsByUserRow, error) {
rows, err := q.db.Query(ctx, listEulaAgreementsByUser, cognitosubjectid)
if err != nil {
return nil, err
}
defer rows.Close()
items := []*ListEulaAgreementsByUserRow{}
for rows.Next() {
var i ListEulaAgreementsByUserRow
if err := rows.Scan(
&i.ID,
&i.Cognitosubjectid,
&i.Useremail,
&i.Eulaversionid,
&i.Agreedat,
&i.Agreedfromip,
&i.Eulaversionstring,
&i.Eulaversiontitle,
); err != nil {
return nil, err
}
items = append(items, &i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listEulaVersions = `-- name: ListEulaVersions :many
SELECT id, version, title, content, effectiveDate, createdAt, createdBy, isCurrent, activatedAt, activatedBy
FROM eulaVersions
ORDER BY createdAt DESC
LIMIT $1 OFFSET $2
`
type ListEulaVersionsParams struct {
Limit int64 `db:"limit"`
Offset int64 `db:"offset"`
}
// Lists all EULA versions with pagination, ordered by createdAt descending
//
// SELECT id, version, title, content, effectiveDate, createdAt, createdBy, isCurrent, activatedAt, activatedBy
// FROM eulaVersions
// ORDER BY createdAt DESC
// LIMIT $1 OFFSET $2
func (q *Queries) ListEulaVersions(ctx context.Context, arg *ListEulaVersionsParams) ([]*Eulaversion, error) {
rows, err := q.db.Query(ctx, listEulaVersions, arg.Limit, arg.Offset)
if err != nil {
return nil, err
}
defer rows.Close()
items := []*Eulaversion{}
for rows.Next() {
var i Eulaversion
if err := rows.Scan(
&i.ID,
&i.Version,
&i.Title,
&i.Content,
&i.Effectivedate,
&i.Createdat,
&i.Createdby,
&i.Iscurrent,
&i.Activatedat,
&i.Activatedby,
); err != nil {
return nil, err
}
items = append(items, &i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const setEulaVersionCurrent = `-- name: SetEulaVersionCurrent :one
UPDATE eulaVersions
SET isCurrent = TRUE, activatedAt = NOW(), activatedBy = $2
WHERE id = $1
RETURNING id, version, title, content, effectiveDate, createdAt, createdBy, isCurrent, activatedAt, activatedBy
`
type SetEulaVersionCurrentParams struct {
ID uuid.UUID `db:"id"`
Activatedby *string `db:"activatedby"`
}
// Sets a specific version as the current active version with audit fields
//
// UPDATE eulaVersions
// SET isCurrent = TRUE, activatedAt = NOW(), activatedBy = $2
// WHERE id = $1
// RETURNING id, version, title, content, effectiveDate, createdAt, createdBy, isCurrent, activatedAt, activatedBy
func (q *Queries) SetEulaVersionCurrent(ctx context.Context, arg *SetEulaVersionCurrentParams) (*Eulaversion, error) {
row := q.db.QueryRow(ctx, setEulaVersionCurrent, arg.ID, arg.Activatedby)
var i Eulaversion
err := row.Scan(
&i.ID,
&i.Version,
&i.Title,
&i.Content,
&i.Effectivedate,
&i.Createdat,
&i.Createdby,
&i.Iscurrent,
&i.Activatedat,
&i.Activatedby,
)
return &i, err
}
const updateEulaVersionMetadata = `-- name: UpdateEulaVersionMetadata :one
UPDATE eulaVersions
SET title = $2, effectiveDate = $3
WHERE id = $1
RETURNING id, version, title, content, effectiveDate, createdAt, createdBy, isCurrent, activatedAt, activatedBy
`
type UpdateEulaVersionMetadataParams struct {
ID uuid.UUID `db:"id"`
Title string `db:"title"`
Effectivedate pgtype.Timestamptz `db:"effectivedate"`
}
// Updates only the metadata (title and effectiveDate) of an EULA version
//
// UPDATE eulaVersions
// SET title = $2, effectiveDate = $3
// WHERE id = $1
// RETURNING id, version, title, content, effectiveDate, createdAt, createdBy, isCurrent, activatedAt, activatedBy
func (q *Queries) UpdateEulaVersionMetadata(ctx context.Context, arg *UpdateEulaVersionMetadataParams) (*Eulaversion, error) {
row := q.db.QueryRow(ctx, updateEulaVersionMetadata, arg.ID, arg.Title, arg.Effectivedate)
var i Eulaversion
err := row.Scan(
&i.ID,
&i.Version,
&i.Title,
&i.Content,
&i.Effectivedate,
&i.Createdat,
&i.Createdby,
&i.Iscurrent,
&i.Activatedat,
&i.Activatedby,
)
return &i, err
}
+22
View File
@@ -524,6 +524,28 @@ type Documentupload struct {
FolderID *uuid.UUID `db:"folder_id"`
}
type Eulaagreement struct {
ID uuid.UUID `db:"id"`
Cognitosubjectid string `db:"cognitosubjectid"`
Useremail string `db:"useremail"`
Eulaversionid uuid.UUID `db:"eulaversionid"`
Agreedat pgtype.Timestamptz `db:"agreedat"`
Agreedfromip string `db:"agreedfromip"`
}
type Eulaversion struct {
ID uuid.UUID `db:"id"`
Version string `db:"version"`
Title string `db:"title"`
Content string `db:"content"`
Effectivedate pgtype.Timestamptz `db:"effectivedate"`
Createdat pgtype.Timestamptz `db:"createdat"`
Createdby string `db:"createdby"`
Iscurrent bool `db:"iscurrent"`
Activatedat pgtype.Timestamptz `db:"activatedat"`
Activatedby *string `db:"activatedby"`
}
// Virtual folder hierarchy for document organization. Database-only - has no direct relationship to S3 storage locations.
type Folder struct {
ID uuid.UUID `db:"id"`