Initial commit of Descrybe v2 without local scratch artifacts.

Drop one-shot tmp/axe scripts and agent i18n scratch so the Gitea tree is deployable.
This commit is contained in:
2026-08-09 22:47:43 +02:00
commit 8580c996c3
1285 changed files with 325780 additions and 0 deletions
+24
View File
@@ -0,0 +1,24 @@
-- name: CreateAPIKey :one
INSERT INTO api_keys (company_id, user_id, name, key_hash, key_prefix)
VALUES ($1, $2, $3, $4, $5)
RETURNING *;
-- name: ListAPIKeysByCompany :many
SELECT id, company_id, user_id, name, key_prefix, last_used_at, revoked_at, created_at, updated_at
FROM api_keys
WHERE company_id = $1 AND revoked_at IS NULL
ORDER BY created_at DESC;
-- name: GetAPIKeyByHash :one
SELECT * FROM api_keys
WHERE key_hash = $1 AND revoked_at IS NULL
LIMIT 1;
-- name: RevokeAPIKey :one
UPDATE api_keys
SET revoked_at = now(), updated_at = now()
WHERE id = $1 AND company_id = $2
RETURNING *;
-- name: TouchAPIKey :exec
UPDATE api_keys SET last_used_at = now() WHERE id = $1;
+34
View File
@@ -0,0 +1,34 @@
-- name: ListAttributes :many
SELECT * FROM attributes
WHERE company_id = $1
ORDER BY name;
-- name: GetAttribute :one
SELECT * FROM attributes
WHERE id = $1 AND company_id = $2
LIMIT 1;
-- name: CreateAttribute :one
INSERT INTO attributes (company_id, attribute_key, name, value_type, unit, example, parent_key)
VALUES ($1, $2, $3, $4, $5, $6, $7)
RETURNING *;
-- name: UpdateAttribute :one
UPDATE attributes
SET name = COALESCE($3, name),
value_type = COALESCE($4, value_type),
unit = COALESCE($5, unit),
example = COALESCE($6, example),
updated_at = now()
WHERE id = $1 AND company_id = $2
RETURNING *;
-- name: DeleteAttribute :exec
DELETE FROM attributes WHERE id = $1 AND company_id = $2;
-- name: ListCategoryAttributes :many
SELECT ca.*, a.attribute_key, a.name AS attribute_name, a.value_type
FROM category_attributes ca
JOIN attributes a ON a.id = ca.attribute_id
WHERE ca.company_id = $1 AND ca.category_unique_id = $2
ORDER BY a.name;
+34
View File
@@ -0,0 +1,34 @@
-- name: GetCreditBalance :one
SELECT * FROM credit_balances WHERE company_id = $1 LIMIT 1;
-- name: UpsertCreditBalance :one
INSERT INTO credit_balances (company_id, total_credits, used_credits, updated_at)
VALUES ($1, $2, $3, now())
ON CONFLICT (company_id) DO UPDATE
SET total_credits = EXCLUDED.total_credits,
used_credits = EXCLUDED.used_credits,
updated_at = now()
RETURNING *;
-- name: GetActiveCompanyPlan :one
SELECT cp.*, p.name AS plan_name, p.monthly_credits, p.max_products
FROM company_plans cp
JOIN plans p ON p.id = cp.plan_id
WHERE cp.company_id = $1 AND cp.is_active = true
ORDER BY cp.created_at DESC
LIMIT 1;
-- name: ListPlans :many
SELECT * FROM plans ORDER BY id;
-- name: CreatePlan :one
INSERT INTO plans (name, description, monthly_credits, yearly_credits, max_products, is_custom, term)
VALUES ($1, $2, $3, $4, $5, $6, $7)
RETURNING *;
-- name: CreateCompanyPlan :one
INSERT INTO company_plans (
company_id, plan_id, is_active, billing_cycle_start, next_billing_date,
is_trial, trial_ends_at, trial_credits
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
RETURNING *;
+19
View File
@@ -0,0 +1,19 @@
-- name: GetCompanyBrand :one
SELECT * FROM company_brand WHERE company_id = $1 LIMIT 1;
-- name: UpsertCompanyBrand :one
INSERT INTO company_brand (
company_id, voice_tone, dos, donts, primary_color, secondary_color, logo_url, preferred_terms, updated_at
) VALUES (
$1, $2, $3, $4, $5, $6, $7, $8, now()
)
ON CONFLICT (company_id) DO UPDATE SET
voice_tone = EXCLUDED.voice_tone,
dos = EXCLUDED.dos,
donts = EXCLUDED.donts,
primary_color = EXCLUDED.primary_color,
secondary_color = EXCLUDED.secondary_color,
logo_url = EXCLUDED.logo_url,
preferred_terms = EXCLUDED.preferred_terms,
updated_at = now()
RETURNING *;
+29
View File
@@ -0,0 +1,29 @@
-- name: ListCategories :many
SELECT * FROM categories
WHERE company_id = $1
ORDER BY path NULLS LAST, position, name;
-- name: GetCategory :one
SELECT * FROM categories
WHERE id = $1 AND company_id = $2
LIMIT 1;
-- name: CreateCategory :one
INSERT INTO categories (
company_id, name, unique_id, parent_unique_id, path, level, position, description
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
RETURNING *;
-- name: UpdateCategory :one
UPDATE categories
SET name = COALESCE($3, name),
description = COALESCE($4, description),
is_active = COALESCE($5, is_active),
title_template = COALESCE($6, title_template),
description_template = COALESCE($7, description_template),
updated_at = now()
WHERE id = $1 AND company_id = $2
RETURNING *;
-- name: DeleteCategory :exec
DELETE FROM categories WHERE id = $1 AND company_id = $2;
+29
View File
@@ -0,0 +1,29 @@
-- name: GetCompanyByID :one
SELECT * FROM companies WHERE id = $1 LIMIT 1;
-- name: GetCompanyByLegacyID :one
SELECT * FROM companies WHERE legacy_company_id = $1 LIMIT 1;
-- name: CreateCompany :one
INSERT INTO companies (name, language, legacy_company_id)
VALUES ($1, $2, $3)
RETURNING *;
-- name: UpdateCompany :one
UPDATE companies
SET name = COALESCE($2, name),
language = COALESCE($3, language),
merge_products_by_gtin = COALESCE($4, merge_products_by_gtin),
updated_at = now()
WHERE id = $1
RETURNING *;
-- name: GetCompanySettings :one
SELECT * FROM company_settings WHERE company_id = $1 LIMIT 1;
-- name: UpsertCompanySettings :one
INSERT INTO company_settings (company_id, settings, updated_at)
VALUES ($1, $2, now())
ON CONFLICT (company_id) DO UPDATE
SET settings = EXCLUDED.settings, updated_at = now()
RETURNING *;
+70
View File
@@ -0,0 +1,70 @@
-- name: ListInputFeeds :many
SELECT * FROM input_feeds
WHERE company_id = $1
ORDER BY created_at DESC;
-- name: GetInputFeed :one
SELECT * FROM input_feeds
WHERE id = $1 AND company_id = $2
LIMIT 1;
-- name: CreateInputFeed :one
INSERT INTO input_feeds (company_id, name, url, feed_type, status, sync_interval_minutes, options)
VALUES ($1, $2, $3, $4, $5, $6, $7)
RETURNING *;
-- name: UpdateInputFeed :one
UPDATE input_feeds
SET name = COALESCE($3, name),
url = COALESCE($4, url),
status = COALESCE($5, status),
sync_interval_minutes = COALESCE($6, sync_interval_minutes),
options = COALESCE($7, options),
updated_at = now()
WHERE id = $1 AND company_id = $2
RETURNING *;
-- name: DeleteInputFeed :exec
DELETE FROM input_feeds WHERE id = $1 AND company_id = $2;
-- name: CreateFeedSyncJob :one
INSERT INTO feed_sync_jobs (feed_id, company_id, status, started_at)
VALUES ($1, $2, $3, now())
RETURNING *;
-- name: UpdateFeedSyncJob :one
UPDATE feed_sync_jobs
SET status = $2, products_synced = $3, error = $4, completed_at = $5, updated_at = now()
WHERE id = $1
RETURNING *;
-- name: ListExportFeeds :many
SELECT * FROM export_feeds
WHERE company_id = $1
ORDER BY created_at DESC;
-- name: GetExportFeed :one
SELECT * FROM export_feeds
WHERE id = $1 AND company_id = $2
LIMIT 1;
-- name: GetExportFeedByToken :one
SELECT * FROM export_feeds
WHERE public_token = $1 AND is_active = true
LIMIT 1;
-- name: CreateExportFeed :one
INSERT INTO export_feeds (company_id, name, source_feed_id, format, template, filters)
VALUES ($1, $2, $3, $4, $5, $6)
RETURNING *;
-- name: GetFeedMapping :one
SELECT * FROM feed_mappings
WHERE feed_id = $1 AND company_id = $2 AND is_active = true
ORDER BY version DESC
LIMIT 1;
-- name: UpsertFeedMapping :one
INSERT INTO feed_mappings (feed_id, company_id, version, mappings, is_active)
VALUES ($1, $2, $3, $4, true)
RETURNING *;
+18
View File
@@ -0,0 +1,18 @@
-- name: CreateInvite :one
INSERT INTO invites (company_id, email, role, token, invited_by, expires_at)
VALUES ($1, $2, $3, $4, $5, $6)
RETURNING *;
-- name: GetInviteByToken :one
SELECT * FROM invites WHERE token = $1 LIMIT 1;
-- name: ListInvitesByCompany :many
SELECT * FROM invites
WHERE company_id = $1 AND accepted_at IS NULL
ORDER BY created_at DESC;
-- name: AcceptInvite :one
UPDATE invites
SET accepted_at = now()
WHERE id = $1 AND accepted_at IS NULL
RETURNING *;
+29
View File
@@ -0,0 +1,29 @@
-- name: CreateMembership :one
INSERT INTO memberships (company_id, user_id, role, status)
VALUES ($1, $2, $3, $4)
RETURNING *;
-- name: GetMembership :one
SELECT * FROM memberships
WHERE company_id = $1 AND user_id = $2
LIMIT 1;
-- name: ListMembershipsByCompany :many
SELECT m.*, u.email, u.name AS user_name
FROM memberships m
JOIN users u ON u.id = m.user_id
WHERE m.company_id = $1
ORDER BY m.created_at;
-- name: ListMembershipsByUser :many
SELECT m.*, c.name AS company_name
FROM memberships m
JOIN companies c ON c.id = m.company_id
WHERE m.user_id = $1 AND m.status = 'active'
ORDER BY m.created_at;
-- name: DeactivateMembership :one
UPDATE memberships
SET status = 'inactive', updated_at = now()
WHERE company_id = $1 AND user_id = $2
RETURNING *;
+62
View File
@@ -0,0 +1,62 @@
-- name: CreateProcessingJob :one
INSERT INTO processing_jobs (
company_id, user_id, status, total_products, processing_type, priority, estimated_tokens
) VALUES ($1, $2, $3, $4, $5, $6, $7)
RETURNING *;
-- name: GetProcessingJob :one
SELECT * FROM processing_jobs
WHERE id = $1 AND company_id = $2
LIMIT 1;
-- name: ListProcessingJobs :many
SELECT * FROM processing_jobs
WHERE company_id = $1
ORDER BY created_at DESC
LIMIT $2;
-- name: UpdateProcessingJobStatus :one
UPDATE processing_jobs
SET status = $2,
processed_products = COALESCE($3, processed_products),
error = COALESCE($4, error),
started_at = COALESCE($5, started_at),
completed_at = COALESCE($6, completed_at),
updated_at = now()
WHERE id = $1
RETURNING *;
-- name: CancelProcessingJob :one
UPDATE processing_jobs
SET status = 'cancelled', completed_at = now(), updated_at = now()
WHERE id = $1 AND company_id = $2 AND status IN ('pending', 'running')
RETURNING *;
-- name: CreateProcessingJobProduct :one
INSERT INTO processing_job_products (job_id, raw_product_id, status)
VALUES ($1, $2, $3)
RETURNING *;
-- name: ListPendingJobProducts :many
SELECT * FROM processing_job_products
WHERE job_id = $1 AND status = 'pending'
ORDER BY created_at
LIMIT $2;
-- name: UpdateJobProductStatus :one
UPDATE processing_job_products
SET status = $2, error = $3, processed_product_id = $4, updated_at = now()
WHERE id = $1
RETURNING *;
-- name: ClaimNextPendingJob :one
UPDATE processing_jobs
SET status = 'running', started_at = now(), updated_at = now()
WHERE id = (
SELECT id FROM processing_jobs
WHERE status = 'pending'
ORDER BY priority DESC, created_at
LIMIT 1
FOR UPDATE SKIP LOCKED
)
RETURNING *;
+48
View File
@@ -0,0 +1,48 @@
-- name: ListRawProducts :many
SELECT * FROM raw_products
WHERE company_id = $1
ORDER BY created_at DESC
LIMIT $2 OFFSET $3;
-- name: CountRawProducts :one
SELECT count(*)::bigint FROM raw_products WHERE company_id = $1;
-- name: GetRawProduct :one
SELECT * FROM raw_products
WHERE id = $1 AND company_id = $2
LIMIT 1;
-- name: UpdateRawProductStatus :one
UPDATE raw_products
SET processing_status = $3, is_processed = $4, updated_at = now()
WHERE id = $1 AND company_id = $2
RETURNING *;
-- name: ListProcessedProducts :many
SELECT * FROM processed_products
WHERE company_id = $1
ORDER BY updated_at DESC
LIMIT $2 OFFSET $3;
-- name: GetProcessedProduct :one
SELECT * FROM processed_products
WHERE id = $1 AND company_id = $2
LIMIT 1;
-- name: UpdateProcessedProduct :one
UPDATE processed_products
SET name = COALESCE($3, name),
description = COALESCE($4, description),
processed_name = COALESCE($5, processed_name),
processed_description = COALESCE($6, processed_description),
category = COALESCE($7, category),
status = COALESCE($8, status),
updated_at = now()
WHERE id = $1 AND company_id = $2
RETURNING *;
-- name: CreateProcessedProduct :one
INSERT INTO processed_products (
company_id, user_id, raw_product_id, product_id, name, description, status, attributes
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
RETURNING *;
+22
View File
@@ -0,0 +1,22 @@
-- name: GetUserByEmail :one
SELECT * FROM users WHERE email = $1 LIMIT 1;
-- name: GetUserByID :one
SELECT * FROM users WHERE id = $1 LIMIT 1;
-- name: GetUserByLegacyID :one
SELECT * FROM users WHERE legacy_user_id = $1 LIMIT 1;
-- name: CreateUser :one
INSERT INTO users (email, name, password_hash, must_set_password, legacy_user_id)
VALUES ($1, $2, $3, $4, $5)
RETURNING *;
-- name: UpdateUserPassword :one
UPDATE users
SET password_hash = $2, must_set_password = false, updated_at = now()
WHERE id = $1
RETURNING *;
-- name: TouchUserLogin :exec
UPDATE users SET last_login_at = now(), updated_at = now() WHERE id = $1;