dana-medical-site/internal/storage/admin_documents.go
2026-10-14 13:33:13 +00:00

95 lines
2.7 KiB
Go

package storage
import (
"context"
"time"
)
type AdminDocument struct {
ID int64 `json:"id"`
Kind string `json:"kind"`
Title string `json:"title"`
Body string `json:"body"`
FileID *int64 `json:"file_id"`
File string `json:"file,omitempty"`
FileMime string `json:"file_mime,omitempty"`
PreviewID *int64 `json:"preview_id"`
Preview string `json:"preview,omitempty"`
IssuedAt *time.Time `json:"issued_at"`
Sort int `json:"sort"`
Published bool `json:"published"`
}
func (s *Storage) AdminDocuments(ctx context.Context) ([]AdminDocument, error) {
rows, err := s.pool.Query(ctx, `
SELECT d.id, d.kind, d.title, d.body, d.file_id, COALESCE(f.path, ''), COALESCE(f.mime, ''),
d.preview_id, COALESCE(p.path, ''), d.issued_at, d.sort, d.published
FROM documents d
LEFT JOIN media f ON f.id = d.file_id
LEFT JOIN media p ON p.id = d.preview_id
ORDER BY d.kind, d.sort, d.id`)
if err != nil {
return nil, err
}
defer rows.Close()
var out []AdminDocument
for rows.Next() {
var d AdminDocument
if err := rows.Scan(&d.ID, &d.Kind, &d.Title, &d.Body, &d.FileID, &d.File, &d.FileMime,
&d.PreviewID, &d.Preview, &d.IssuedAt, &d.Sort, &d.Published); err != nil {
return nil, err
}
out = append(out, d)
}
return out, rows.Err()
}
type DocumentInput struct {
Kind string
Title string
Body string
FileID *int64
PreviewID *int64
IssuedAt *time.Time
Sort int
Published bool
}
func (s *Storage) AdminCreateDocument(ctx context.Context, in DocumentInput) (int64, error) {
var id int64
err := s.pool.QueryRow(ctx, `
INSERT INTO documents (kind, title, body, file_id, preview_id, issued_at, sort, published)
VALUES ($1,$2,$3,$4,$5,$6,$7,$8)
RETURNING id`,
in.Kind, in.Title, in.Body, in.FileID, in.PreviewID, in.IssuedAt, in.Sort, in.Published).Scan(&id)
return id, wrapConflict(err)
}
func (s *Storage) AdminUpdateDocument(ctx context.Context, id int64, in DocumentInput) error {
tag, err := s.pool.Exec(ctx, `
UPDATE documents SET kind=$2, title=$3, body=$4, file_id=$5, preview_id=$6, issued_at=$7,
sort=$8, published=$9
WHERE id=$1`,
id, in.Kind, in.Title, in.Body, in.FileID, in.PreviewID, in.IssuedAt, in.Sort, in.Published)
if err != nil {
return wrapConflict(err)
}
if tag.RowsAffected() == 0 {
return ErrNotFound
}
return nil
}
// AdminDeleteDocument удаляет запись; файлы остаются в медиатеке.
func (s *Storage) AdminDeleteDocument(ctx context.Context, id int64) error {
tag, err := s.pool.Exec(ctx, `DELETE FROM documents WHERE id=$1`, id)
if err != nil {
return err
}
if tag.RowsAffected() == 0 {
return ErrNotFound
}
return nil
}