mirror of
https://github.com/Dvorinka/Containr.git
synced 2026-10-28 07:41:27 +00:00
Backend: service_templates.is_public lets owners publish user templates to the anonymous catalog (GET /api/v1/templates), mirroring Railway's marketplace publish flow. Migration, sqlc queries, visibility rules, and openapi.yaml updated; types regenerated. App: template editor gains a "List in the public catalog" checkbox; Public badge on catalog cards and detail view. Site: new templates.html catalog page - search, category filters, Official vs Community badges, detail modal with variables and copyable import JSON. Fetches the live catalog from a reachable instance (?api= or localStorage override) and falls back to templates.json, generated from SeedTemplates via cmd/dumptemplates. Shared styles extracted to style.css. Vercel: project connected to GitHub repo with rootDirectory=site; .vercelignore limits CLI uploads to site/ so `vercel deploy --prod` from repo root matches git builds. Authored By: TDvorak <[email protected]> Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
445 lines
11 KiB
Go
445 lines
11 KiB
Go
// Code generated by sqlc. DO NOT EDIT.
|
|
// versions:
|
|
// sqlc v1.31.1
|
|
// source: templates.sql
|
|
|
|
package sqlcdb
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"encoding/json"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/sqlc-dev/pqtype"
|
|
)
|
|
|
|
const countServicesByProjectAndName = `-- name: CountServicesByProjectAndName :one
|
|
SELECT COUNT(*)
|
|
FROM services
|
|
WHERE project_id = $1 AND name = $2
|
|
`
|
|
|
|
type CountServicesByProjectAndNameParams struct {
|
|
ProjectID uuid.UUID `json:"project_id"`
|
|
Name string `json:"name"`
|
|
}
|
|
|
|
func (q *Queries) CountServicesByProjectAndName(ctx context.Context, arg CountServicesByProjectAndNameParams) (int64, error) {
|
|
row := q.db.QueryRowContext(ctx, countServicesByProjectAndName, arg.ProjectID, arg.Name)
|
|
var count int64
|
|
err := row.Scan(&count)
|
|
return count, err
|
|
}
|
|
|
|
const createServiceFromTemplate = `-- name: CreateServiceFromTemplate :exec
|
|
INSERT INTO services (
|
|
id,
|
|
project_id,
|
|
name,
|
|
environment_id,
|
|
service_type,
|
|
source_type,
|
|
source_url,
|
|
image_name,
|
|
build_command,
|
|
start_command,
|
|
type,
|
|
status,
|
|
image,
|
|
command,
|
|
environment,
|
|
cpu,
|
|
memory,
|
|
created_at,
|
|
updated_at
|
|
)
|
|
VALUES (
|
|
$1,
|
|
$2,
|
|
$3,
|
|
$4,
|
|
$5,
|
|
$6,
|
|
$7,
|
|
$8,
|
|
$9,
|
|
$10,
|
|
$11,
|
|
$12,
|
|
$13,
|
|
$14,
|
|
$15,
|
|
$16,
|
|
$17,
|
|
$18,
|
|
$19
|
|
)
|
|
`
|
|
|
|
type CreateServiceFromTemplateParams struct {
|
|
ID uuid.UUID `json:"id"`
|
|
ProjectID uuid.UUID `json:"project_id"`
|
|
Name string `json:"name"`
|
|
EnvironmentID uuid.UUID `json:"environment_id"`
|
|
ServiceType string `json:"service_type"`
|
|
SourceType string `json:"source_type"`
|
|
SourceUrl sql.NullString `json:"source_url"`
|
|
ImageName sql.NullString `json:"image_name"`
|
|
BuildCommand sql.NullString `json:"build_command"`
|
|
StartCommand sql.NullString `json:"start_command"`
|
|
Type sql.NullString `json:"type"`
|
|
Status sql.NullString `json:"status"`
|
|
Image sql.NullString `json:"image"`
|
|
Command sql.NullString `json:"command"`
|
|
Environment sql.NullString `json:"environment"`
|
|
Cpu sql.NullString `json:"cpu"`
|
|
Memory sql.NullString `json:"memory"`
|
|
CreatedAt sql.NullTime `json:"created_at"`
|
|
UpdatedAt sql.NullTime `json:"updated_at"`
|
|
}
|
|
|
|
func (q *Queries) CreateServiceFromTemplate(ctx context.Context, arg CreateServiceFromTemplateParams) error {
|
|
_, err := q.db.ExecContext(ctx, createServiceFromTemplate,
|
|
arg.ID,
|
|
arg.ProjectID,
|
|
arg.Name,
|
|
arg.EnvironmentID,
|
|
arg.ServiceType,
|
|
arg.SourceType,
|
|
arg.SourceUrl,
|
|
arg.ImageName,
|
|
arg.BuildCommand,
|
|
arg.StartCommand,
|
|
arg.Type,
|
|
arg.Status,
|
|
arg.Image,
|
|
arg.Command,
|
|
arg.Environment,
|
|
arg.Cpu,
|
|
arg.Memory,
|
|
arg.CreatedAt,
|
|
arg.UpdatedAt,
|
|
)
|
|
return err
|
|
}
|
|
|
|
const createUserTemplate = `-- name: CreateUserTemplate :exec
|
|
INSERT INTO service_templates (id, name, description, category, logo, config, variables, is_official, owner_id, is_public)
|
|
VALUES (
|
|
$1,
|
|
$2,
|
|
$3,
|
|
$4,
|
|
$5,
|
|
$6,
|
|
$7,
|
|
false,
|
|
$8,
|
|
$9
|
|
)
|
|
`
|
|
|
|
type CreateUserTemplateParams struct {
|
|
ID string `json:"id"`
|
|
Name string `json:"name"`
|
|
Description sql.NullString `json:"description"`
|
|
Category string `json:"category"`
|
|
Logo sql.NullString `json:"logo"`
|
|
Config json.RawMessage `json:"config"`
|
|
Variables pqtype.NullRawMessage `json:"variables"`
|
|
OwnerID uuid.NullUUID `json:"owner_id"`
|
|
IsPublic bool `json:"is_public"`
|
|
}
|
|
|
|
func (q *Queries) CreateUserTemplate(ctx context.Context, arg CreateUserTemplateParams) error {
|
|
_, err := q.db.ExecContext(ctx, createUserTemplate,
|
|
arg.ID,
|
|
arg.Name,
|
|
arg.Description,
|
|
arg.Category,
|
|
arg.Logo,
|
|
arg.Config,
|
|
arg.Variables,
|
|
arg.OwnerID,
|
|
arg.IsPublic,
|
|
)
|
|
return err
|
|
}
|
|
|
|
const deleteUserTemplate = `-- name: DeleteUserTemplate :execrows
|
|
DELETE FROM service_templates
|
|
WHERE id = $1
|
|
AND owner_id = $2
|
|
AND is_official = false
|
|
`
|
|
|
|
type DeleteUserTemplateParams struct {
|
|
ID string `json:"id"`
|
|
OwnerID uuid.NullUUID `json:"owner_id"`
|
|
}
|
|
|
|
func (q *Queries) DeleteUserTemplate(ctx context.Context, arg DeleteUserTemplateParams) (int64, error) {
|
|
result, err := q.db.ExecContext(ctx, deleteUserTemplate, arg.ID, arg.OwnerID)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
return result.RowsAffected()
|
|
}
|
|
|
|
const getProjectOwnerID = `-- name: GetProjectOwnerID :one
|
|
SELECT owner_id
|
|
FROM projects
|
|
WHERE id = $1
|
|
`
|
|
|
|
func (q *Queries) GetProjectOwnerID(ctx context.Context, id uuid.UUID) (uuid.UUID, error) {
|
|
row := q.db.QueryRowContext(ctx, getProjectOwnerID, id)
|
|
var owner_id uuid.UUID
|
|
err := row.Scan(&owner_id)
|
|
return owner_id, err
|
|
}
|
|
|
|
const getServiceTemplateByID = `-- name: GetServiceTemplateByID :one
|
|
SELECT id, name, description, category, logo, config, variables, is_official, owner_id, is_public, created_at, updated_at
|
|
FROM service_templates
|
|
WHERE id = $1
|
|
`
|
|
|
|
func (q *Queries) GetServiceTemplateByID(ctx context.Context, id string) (ServiceTemplate, error) {
|
|
row := q.db.QueryRowContext(ctx, getServiceTemplateByID, id)
|
|
var i ServiceTemplate
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.Name,
|
|
&i.Description,
|
|
&i.Category,
|
|
&i.Logo,
|
|
&i.Config,
|
|
&i.Variables,
|
|
&i.IsOfficial,
|
|
&i.OwnerID,
|
|
&i.IsPublic,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const listServiceTemplatesByCategoryForUser = `-- name: ListServiceTemplatesByCategoryForUser :many
|
|
SELECT id, name, description, category, logo, config, variables, is_official, owner_id, is_public, created_at, updated_at
|
|
FROM service_templates
|
|
WHERE category = $1
|
|
AND (is_official = true OR is_public = true OR owner_id = $2)
|
|
ORDER BY is_official DESC, name ASC
|
|
`
|
|
|
|
type ListServiceTemplatesByCategoryForUserParams struct {
|
|
Category string `json:"category"`
|
|
OwnerID uuid.NullUUID `json:"owner_id"`
|
|
}
|
|
|
|
func (q *Queries) ListServiceTemplatesByCategoryForUser(ctx context.Context, arg ListServiceTemplatesByCategoryForUserParams) ([]ServiceTemplate, error) {
|
|
rows, err := q.db.QueryContext(ctx, listServiceTemplatesByCategoryForUser, arg.Category, arg.OwnerID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
items := []ServiceTemplate{}
|
|
for rows.Next() {
|
|
var i ServiceTemplate
|
|
if err := rows.Scan(
|
|
&i.ID,
|
|
&i.Name,
|
|
&i.Description,
|
|
&i.Category,
|
|
&i.Logo,
|
|
&i.Config,
|
|
&i.Variables,
|
|
&i.IsOfficial,
|
|
&i.OwnerID,
|
|
&i.IsPublic,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
); err != nil {
|
|
return nil, err
|
|
}
|
|
items = append(items, i)
|
|
}
|
|
if err := rows.Close(); err != nil {
|
|
return nil, err
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return nil, err
|
|
}
|
|
return items, nil
|
|
}
|
|
|
|
const listServiceTemplatesForUser = `-- name: ListServiceTemplatesForUser :many
|
|
SELECT id, name, description, category, logo, config, variables, is_official, owner_id, is_public, created_at, updated_at
|
|
FROM service_templates
|
|
WHERE is_official = true OR is_public = true OR owner_id = $1
|
|
ORDER BY is_official DESC, name ASC
|
|
`
|
|
|
|
func (q *Queries) ListServiceTemplatesForUser(ctx context.Context, ownerID uuid.NullUUID) ([]ServiceTemplate, error) {
|
|
rows, err := q.db.QueryContext(ctx, listServiceTemplatesForUser, ownerID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
items := []ServiceTemplate{}
|
|
for rows.Next() {
|
|
var i ServiceTemplate
|
|
if err := rows.Scan(
|
|
&i.ID,
|
|
&i.Name,
|
|
&i.Description,
|
|
&i.Category,
|
|
&i.Logo,
|
|
&i.Config,
|
|
&i.Variables,
|
|
&i.IsOfficial,
|
|
&i.OwnerID,
|
|
&i.IsPublic,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
); err != nil {
|
|
return nil, err
|
|
}
|
|
items = append(items, i)
|
|
}
|
|
if err := rows.Close(); err != nil {
|
|
return nil, err
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return nil, err
|
|
}
|
|
return items, nil
|
|
}
|
|
|
|
const updateUserTemplate = `-- name: UpdateUserTemplate :execrows
|
|
UPDATE service_templates
|
|
SET name = $1,
|
|
description = $2,
|
|
category = $3,
|
|
logo = $4,
|
|
config = $5,
|
|
variables = $6,
|
|
is_public = $7,
|
|
updated_at = NOW()
|
|
WHERE id = $8
|
|
AND owner_id = $9
|
|
AND is_official = false
|
|
`
|
|
|
|
type UpdateUserTemplateParams struct {
|
|
Name string `json:"name"`
|
|
Description sql.NullString `json:"description"`
|
|
Category string `json:"category"`
|
|
Logo sql.NullString `json:"logo"`
|
|
Config json.RawMessage `json:"config"`
|
|
Variables pqtype.NullRawMessage `json:"variables"`
|
|
IsPublic bool `json:"is_public"`
|
|
ID string `json:"id"`
|
|
OwnerID uuid.NullUUID `json:"owner_id"`
|
|
}
|
|
|
|
func (q *Queries) UpdateUserTemplate(ctx context.Context, arg UpdateUserTemplateParams) (int64, error) {
|
|
result, err := q.db.ExecContext(ctx, updateUserTemplate,
|
|
arg.Name,
|
|
arg.Description,
|
|
arg.Category,
|
|
arg.Logo,
|
|
arg.Config,
|
|
arg.Variables,
|
|
arg.IsPublic,
|
|
arg.ID,
|
|
arg.OwnerID,
|
|
)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
return result.RowsAffected()
|
|
}
|
|
|
|
const upsertEnvironmentVariable = `-- name: UpsertEnvironmentVariable :exec
|
|
INSERT INTO environment_variables (id, service_id, key, value, is_secret, created_at, updated_at)
|
|
VALUES ($1, $2, $3, $4, $5, $6, $7)
|
|
ON CONFLICT (service_id, key) DO UPDATE
|
|
SET value = EXCLUDED.value,
|
|
is_secret = EXCLUDED.is_secret,
|
|
updated_at = EXCLUDED.updated_at
|
|
`
|
|
|
|
type UpsertEnvironmentVariableParams struct {
|
|
ID uuid.UUID `json:"id"`
|
|
ServiceID uuid.UUID `json:"service_id"`
|
|
Key string `json:"key"`
|
|
Value string `json:"value"`
|
|
IsSecret sql.NullBool `json:"is_secret"`
|
|
CreatedAt sql.NullTime `json:"created_at"`
|
|
UpdatedAt sql.NullTime `json:"updated_at"`
|
|
}
|
|
|
|
func (q *Queries) UpsertEnvironmentVariable(ctx context.Context, arg UpsertEnvironmentVariableParams) error {
|
|
_, err := q.db.ExecContext(ctx, upsertEnvironmentVariable,
|
|
arg.ID,
|
|
arg.ServiceID,
|
|
arg.Key,
|
|
arg.Value,
|
|
arg.IsSecret,
|
|
arg.CreatedAt,
|
|
arg.UpdatedAt,
|
|
)
|
|
return err
|
|
}
|
|
|
|
const upsertServiceTemplate = `-- name: UpsertServiceTemplate :exec
|
|
INSERT INTO service_templates (id, name, description, category, logo, config, variables, is_official)
|
|
VALUES (
|
|
$1,
|
|
$2,
|
|
$3,
|
|
$4,
|
|
$5,
|
|
$6,
|
|
$7,
|
|
$8
|
|
)
|
|
ON CONFLICT (id) DO UPDATE
|
|
SET name = EXCLUDED.name,
|
|
description = EXCLUDED.description,
|
|
category = EXCLUDED.category,
|
|
logo = EXCLUDED.logo,
|
|
config = EXCLUDED.config,
|
|
variables = EXCLUDED.variables,
|
|
is_official = EXCLUDED.is_official,
|
|
updated_at = NOW()
|
|
`
|
|
|
|
type UpsertServiceTemplateParams struct {
|
|
ID string `json:"id"`
|
|
Name string `json:"name"`
|
|
Description sql.NullString `json:"description"`
|
|
Category string `json:"category"`
|
|
Logo sql.NullString `json:"logo"`
|
|
Config json.RawMessage `json:"config"`
|
|
Variables pqtype.NullRawMessage `json:"variables"`
|
|
IsOfficial sql.NullBool `json:"is_official"`
|
|
}
|
|
|
|
func (q *Queries) UpsertServiceTemplate(ctx context.Context, arg UpsertServiceTemplateParams) error {
|
|
_, err := q.db.ExecContext(ctx, upsertServiceTemplate,
|
|
arg.ID,
|
|
arg.Name,
|
|
arg.Description,
|
|
arg.Category,
|
|
arg.Logo,
|
|
arg.Config,
|
|
arg.Variables,
|
|
arg.IsOfficial,
|
|
)
|
|
return err
|
|
}
|