feat(backend): implement task creation and admin web
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
package sqlite
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
|
||||
"cmroubao/backend-api/internal/domain"
|
||||
"cmroubao/backend-api/internal/usecase"
|
||||
)
|
||||
|
||||
const assetUploadOperation = "UPLOAD_TASK_REFERENCE"
|
||||
|
||||
func (s *Store) CreateAssetIdempotent(
|
||||
ctx context.Context,
|
||||
candidate domain.Asset,
|
||||
idempotencyKey string,
|
||||
requestHash string,
|
||||
) (domain.Asset, bool, error) {
|
||||
tx, err := s.db.BeginTx(ctx, nil)
|
||||
if err != nil {
|
||||
return domain.Asset{}, false, repositoryFailure(err)
|
||||
}
|
||||
defer func() { _ = tx.Rollback() }()
|
||||
|
||||
existingHash, resourceID, found, err := lookupIdempotency(
|
||||
ctx,
|
||||
tx,
|
||||
candidate.CreatorSubject,
|
||||
assetUploadOperation,
|
||||
idempotencyKey,
|
||||
)
|
||||
if err != nil {
|
||||
return domain.Asset{}, false, err
|
||||
}
|
||||
if found {
|
||||
if existingHash != requestHash {
|
||||
return domain.Asset{}, false, usecase.ErrIdempotencyConflict
|
||||
}
|
||||
existing, err := getAssetByID(
|
||||
ctx,
|
||||
tx,
|
||||
candidate.CreatorSubject,
|
||||
resourceID,
|
||||
)
|
||||
if err != nil {
|
||||
return domain.Asset{}, false, err
|
||||
}
|
||||
if err := tx.Commit(); err != nil {
|
||||
return domain.Asset{}, false, repositoryFailure(err)
|
||||
}
|
||||
return existing, false, nil
|
||||
}
|
||||
|
||||
_, err = tx.ExecContext(
|
||||
ctx,
|
||||
`INSERT INTO assets (
|
||||
id, creator_subject, purpose, media_type, size_bytes,
|
||||
sha256, storage_key, created_at
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
|
||||
candidate.ID,
|
||||
candidate.CreatorSubject,
|
||||
candidate.Purpose,
|
||||
candidate.MediaType,
|
||||
candidate.SizeBytes,
|
||||
candidate.SHA256,
|
||||
candidate.StorageKey,
|
||||
formatTimestamp(candidate.CreatedAt),
|
||||
)
|
||||
if err != nil {
|
||||
return domain.Asset{}, false, repositoryFailure(err)
|
||||
}
|
||||
if err := insertIdempotency(
|
||||
ctx,
|
||||
tx,
|
||||
candidate.CreatorSubject,
|
||||
assetUploadOperation,
|
||||
idempotencyKey,
|
||||
requestHash,
|
||||
"ASSET",
|
||||
candidate.ID,
|
||||
candidate.CreatedAt,
|
||||
); err != nil {
|
||||
return domain.Asset{}, false, err
|
||||
}
|
||||
if err := tx.Commit(); err != nil {
|
||||
return domain.Asset{}, false, repositoryFailure(err)
|
||||
}
|
||||
return candidate, true, nil
|
||||
}
|
||||
|
||||
func (s *Store) GetAsset(
|
||||
ctx context.Context,
|
||||
creatorSubject string,
|
||||
assetID string,
|
||||
) (domain.Asset, error) {
|
||||
return getAssetByID(ctx, s.db, creatorSubject, assetID)
|
||||
}
|
||||
|
||||
var _ usecase.AssetRepository = (*Store)(nil)
|
||||
var _ queryRower = (*sql.Tx)(nil)
|
||||
Reference in New Issue
Block a user