feat(my-drafts): schema drafts тоже в "Мои черновики"

This commit is contained in:
Александр Зимин
2026-05-13 12:45:45 +00:00
parent 1b20db5059
commit f096b5746d
5 changed files with 218 additions and 11 deletions
@@ -130,6 +130,20 @@ public class SchemaDraftService {
return repository.findPendingReview(pageable);
}
/**
* Maker self-tracking — все schema drafts которые создал actor, любой
* статус (DRAFT / REVIEW_PENDING / APPROVED / REJECTED / CHANGES_REQUESTED
* / WITHDRAWN / PUBLISHED), отсортированы createdAt DESC.
*
* <p>Зеркало record-side {@code DraftService.listByMaker} — frontend
* "Мои черновики" (route {@code /my-drafts}) показывает оба типа,
* чтобы maker не запоминал где какие drafts лежат.
*/
@Transactional(readOnly = true)
public Page<DictionarySchemaDraft> listByMaker(String makerId, Pageable pageable) {
return repository.findByMaker(makerId, pageable);
}
// ─────────────────────────────────────────────────────────────────────
// Mutators (state machine transitions)
// ─────────────────────────────────────────────────────────────────────
@@ -41,6 +41,7 @@ import java.util.UUID;
* GET /api/v1/dictionaries/{name}/drafts/active
* GET /api/v1/dictionaries/{name}/drafts/{draftId}
* GET /api/v1/admin/schema-reviews/pending (pool queue)
* GET /api/v1/admin/schema-drafts/me (maker tracking)
* </pre>
*
* <p>{@code {name}} в path передаётся для красивых URL'ов + кэширования
@@ -211,4 +212,41 @@ public class SchemaDraftController {
"totalElements", pg.getTotalElements(),
"totalPages", pg.getTotalPages());
}
/**
* Maker self-tracking — все schema drafts актора, любой статус.
* Зеркало record-side {@code /api/v1/drafts/me}. Frontend "Мои черновики"
* объединяет обе очереди (record + schema), чтобы пользователь не
* запоминал какой тип где лежит.
*
* <p>Sorted createdAt DESC (newest first) — самые свежие drafts наверху,
* legacy / approved уходят вниз. UI добавляет фильтр по status.
*/
@GetMapping("/api/v1/admin/schema-drafts/me")
public Map<String, Object> myDrafts(
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "50") int size) {
String makerId = currentUserId();
var pg = draftService.listByMaker(makerId, PageRequest.of(page, Math.min(size, 200)));
List<SchemaDraftResponse> items = pg.getContent().stream()
.map(d -> {
DictionaryDefinition def = definitionService.findById(d.getDictionaryId());
return SchemaDraftResponse.from(d, def.getName());
})
.toList();
return Map.of(
"items", items,
"page", pg.getNumber(),
"size", pg.getSize(),
"totalElements", pg.getTotalElements(),
"totalPages", pg.getTotalPages());
}
/** Resolve current user from JWT subject. Fallback "anonymous" если auth off. */
private static String currentUserId() {
var auth = org.springframework.security.core.context.SecurityContextHolder
.getContext().getAuthentication();
if (auth == null || !auth.isAuthenticated()) return "anonymous";
return auth.getName();
}
}