feat: implement entity and wiki management services, repositories, and routes with associated controllers
Build and Release / release (push) Successful in 1m34s
Build and Release / release (push) Successful in 1m34s
This commit is contained in:
@@ -159,6 +159,7 @@ func (s *FiberServer) SetupServer(
|
|||||||
routes.EntityRoutes(s.App, entityController)
|
routes.EntityRoutes(s.App, entityController)
|
||||||
routes.GeometryRoutes(s.App, geometryController)
|
routes.GeometryRoutes(s.App, geometryController)
|
||||||
routes.WikiRoutes(s.App, wikiController)
|
routes.WikiRoutes(s.App, wikiController)
|
||||||
|
routes.RelationRoutes(s.App, wikiController, entityController)
|
||||||
routes.ProjectRoutes(s.App, projectController, commitController, userRepo)
|
routes.ProjectRoutes(s.App, projectController, commitController, userRepo)
|
||||||
routes.SubmissionRoutes(s.App, submissionController, userRepo)
|
routes.SubmissionRoutes(s.App, submissionController, userRepo)
|
||||||
routes.ChatbotRoutes(s.App, chatbotController, userRepo)
|
routes.ChatbotRoutes(s.App, chatbotController, userRepo)
|
||||||
|
|||||||
@@ -67,4 +67,9 @@ FROM entities
|
|||||||
WHERE slug = $1 AND is_deleted = false;
|
WHERE slug = $1 AND is_deleted = false;
|
||||||
|
|
||||||
-- name: GetEntitiesBySlugs :many
|
-- name: GetEntitiesBySlugs :many
|
||||||
SELECT * FROM entities WHERE slug = ANY($1::text[]) AND is_deleted = false;
|
SELECT * FROM entities WHERE slug = ANY($1::text[]) AND is_deleted = false;
|
||||||
|
|
||||||
|
-- name: GetEntityIDsByGeometryIDs :many
|
||||||
|
SELECT geometry_id, entity_id
|
||||||
|
FROM entity_geometries
|
||||||
|
WHERE geometry_id = ANY($1::uuid[]);
|
||||||
@@ -127,3 +127,8 @@ SELECT id, wiki_id, title, created_at
|
|||||||
FROM wiki_content
|
FROM wiki_content
|
||||||
WHERE wiki_id = ANY($1::uuid[]) AND is_deleted = false
|
WHERE wiki_id = ANY($1::uuid[]) AND is_deleted = false
|
||||||
ORDER BY created_at DESC;
|
ORDER BY created_at DESC;
|
||||||
|
|
||||||
|
-- name: GetWikiIDsByEntityIDs :many
|
||||||
|
SELECT entity_id, wiki_id
|
||||||
|
FROM entity_wikis
|
||||||
|
WHERE entity_id = ANY($1::uuid[]);
|
||||||
|
|||||||
@@ -136,3 +136,40 @@ func (h *EntityController) SearchEntities(c fiber.Ctx) error {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetEntitiesByGeometryIDs handles fetching entities by a list of geometry IDs.
|
||||||
|
// @Summary Get entities by geometry IDs
|
||||||
|
// @Description Get entities grouped by geometry IDs
|
||||||
|
// @Tags Relations
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param query query request.GetEntitiesByGeometryIDsDto true "Query Parameters"
|
||||||
|
// @Success 200 {object} response.CommonResponse
|
||||||
|
// @Failure 400 {object} response.CommonResponse
|
||||||
|
// @Failure 500 {object} response.CommonResponse
|
||||||
|
// @Router /relations/entities-by-geometries [get]
|
||||||
|
func (h *EntityController) GetEntitiesByGeometryIDs(c fiber.Ctx) error {
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
dto := &request.GetEntitiesByGeometryIDsDto{}
|
||||||
|
if err := validator.ValidateQueryDto(c, dto); err != nil {
|
||||||
|
return c.Status(fiber.StatusBadRequest).JSON(response.CommonResponse{
|
||||||
|
Status: false,
|
||||||
|
Errors: err,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := h.service.GetEntitiesByGeometryIDs(ctx, dto)
|
||||||
|
if err != nil {
|
||||||
|
return c.Status(err.Code).JSON(response.CommonResponse{
|
||||||
|
Status: false,
|
||||||
|
Message: err.Message,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.Status(fiber.StatusOK).JSON(response.CommonResponse{
|
||||||
|
Status: true,
|
||||||
|
Data: res,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -163,3 +163,76 @@ func (h *WikiController) GetWikiContentById(c fiber.Ctx) error {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetWikisByEntityIDs handles fetching wikis by a list of entity IDs.
|
||||||
|
// @Summary Get wikis by entity IDs
|
||||||
|
// @Description Get wikis grouped by entity IDs
|
||||||
|
// @Tags Relations
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param query query request.GetWikisByEntityIDsDto true "Query Parameters"
|
||||||
|
// @Success 200 {object} response.CommonResponse
|
||||||
|
// @Failure 400 {object} response.CommonResponse
|
||||||
|
// @Failure 500 {object} response.CommonResponse
|
||||||
|
// @Router /relations/wikis-by-entities [get]
|
||||||
|
func (h *WikiController) GetWikisByEntityIDs(c fiber.Ctx) error {
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
dto := &request.GetWikisByEntityIDsDto{}
|
||||||
|
if err := validator.ValidateQueryDto(c, dto); err != nil {
|
||||||
|
return c.Status(fiber.StatusBadRequest).JSON(response.CommonResponse{
|
||||||
|
Status: false,
|
||||||
|
Errors: err,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := h.service.GetWikisByEntityIDs(ctx, dto)
|
||||||
|
if err != nil {
|
||||||
|
return c.Status(err.Code).JSON(response.CommonResponse{
|
||||||
|
Status: false,
|
||||||
|
Message: err.Message,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.Status(fiber.StatusOK).JSON(response.CommonResponse{
|
||||||
|
Status: true,
|
||||||
|
Data: res,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetWikiContentsPreviewByIDs handles fetching wiki content previews by a list of IDs.
|
||||||
|
// @Summary Get wiki content previews by IDs
|
||||||
|
// @Description Get previews of specific wiki contents by a list of their IDs
|
||||||
|
// @Tags Relations
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param query query request.GetWikiContentsPreviewDto true "Query Parameters"
|
||||||
|
// @Success 200 {object} response.CommonResponse
|
||||||
|
// @Failure 400 {object} response.CommonResponse
|
||||||
|
// @Failure 500 {object} response.CommonResponse
|
||||||
|
// @Router /relations/wiki-contents/preview [get]
|
||||||
|
func (h *WikiController) GetWikiContentsPreviewByIDs(c fiber.Ctx) error {
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
dto := &request.GetWikiContentsPreviewDto{}
|
||||||
|
if err := validator.ValidateQueryDto(c, dto); err != nil {
|
||||||
|
return c.Status(fiber.StatusBadRequest).JSON(response.CommonResponse{
|
||||||
|
Status: false,
|
||||||
|
Errors: err,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := h.service.GetWikiContentsPreviewByIDs(ctx, dto)
|
||||||
|
if err != nil {
|
||||||
|
return c.Status(err.Code).JSON(response.CommonResponse{
|
||||||
|
Status: false,
|
||||||
|
Message: err.Message,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.Status(fiber.StatusOK).JSON(response.CommonResponse{
|
||||||
|
Status: true,
|
||||||
|
Data: res,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package request
|
||||||
|
|
||||||
|
type GetWikisByEntityIDsDto struct {
|
||||||
|
EntityIDs []string `json:"entity_ids" query:"entity_ids" validate:"required,min=1,dive,uuid"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetEntitiesByGeometryIDsDto struct {
|
||||||
|
GeometryIDs []string `json:"geometry_ids" query:"geometry_ids" validate:"required,min=1,dive,uuid"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetWikiContentsPreviewDto struct {
|
||||||
|
IDs []string `json:"ids" query:"ids" validate:"required,min=1,dive,uuid"`
|
||||||
|
}
|
||||||
@@ -29,3 +29,9 @@ type WikiContentResponse struct {
|
|||||||
Preview string `json:"preview"`
|
Preview string `json:"preview"`
|
||||||
CreatedAt *time.Time `json:"created_at"`
|
CreatedAt *time.Time `json:"created_at"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type WikiContentPreviewResponse struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Preview string `json:"preview"`
|
||||||
|
CreatedAt *time.Time `json:"created_at"`
|
||||||
|
}
|
||||||
|
|||||||
@@ -242,6 +242,37 @@ func (q *Queries) GetEntityBySlug(ctx context.Context, slug pgtype.Text) (Entity
|
|||||||
return i, err
|
return i, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getEntityIDsByGeometryIDs = `-- name: GetEntityIDsByGeometryIDs :many
|
||||||
|
SELECT geometry_id, entity_id
|
||||||
|
FROM entity_geometries
|
||||||
|
WHERE geometry_id = ANY($1::uuid[])
|
||||||
|
`
|
||||||
|
|
||||||
|
type GetEntityIDsByGeometryIDsRow struct {
|
||||||
|
GeometryID pgtype.UUID `json:"geometry_id"`
|
||||||
|
EntityID pgtype.UUID `json:"entity_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) GetEntityIDsByGeometryIDs(ctx context.Context, dollar_1 []pgtype.UUID) ([]GetEntityIDsByGeometryIDsRow, error) {
|
||||||
|
rows, err := q.db.Query(ctx, getEntityIDsByGeometryIDs, dollar_1)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
items := []GetEntityIDsByGeometryIDsRow{}
|
||||||
|
for rows.Next() {
|
||||||
|
var i GetEntityIDsByGeometryIDsRow
|
||||||
|
if err := rows.Scan(&i.GeometryID, &i.EntityID); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
items = append(items, i)
|
||||||
|
}
|
||||||
|
if err := rows.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return items, nil
|
||||||
|
}
|
||||||
|
|
||||||
const searchEntities = `-- name: SearchEntities :many
|
const searchEntities = `-- name: SearchEntities :many
|
||||||
SELECT id, project_id, name, slug, description, status, time_start, time_end, is_deleted, created_at, updated_at
|
SELECT id, project_id, name, slug, description, status, time_start, time_end, is_deleted, created_at, updated_at
|
||||||
FROM entities
|
FROM entities
|
||||||
|
|||||||
@@ -370,6 +370,37 @@ func (q *Queries) GetWikiContentCount(ctx context.Context, wikiID pgtype.UUID) (
|
|||||||
return count, err
|
return count, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getWikiIDsByEntityIDs = `-- name: GetWikiIDsByEntityIDs :many
|
||||||
|
SELECT entity_id, wiki_id
|
||||||
|
FROM entity_wikis
|
||||||
|
WHERE entity_id = ANY($1::uuid[])
|
||||||
|
`
|
||||||
|
|
||||||
|
type GetWikiIDsByEntityIDsRow struct {
|
||||||
|
EntityID pgtype.UUID `json:"entity_id"`
|
||||||
|
WikiID pgtype.UUID `json:"wiki_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) GetWikiIDsByEntityIDs(ctx context.Context, dollar_1 []pgtype.UUID) ([]GetWikiIDsByEntityIDsRow, error) {
|
||||||
|
rows, err := q.db.Query(ctx, getWikiIDsByEntityIDs, dollar_1)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
items := []GetWikiIDsByEntityIDsRow{}
|
||||||
|
for rows.Next() {
|
||||||
|
var i GetWikiIDsByEntityIDsRow
|
||||||
|
if err := rows.Scan(&i.EntityID, &i.WikiID); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
items = append(items, i)
|
||||||
|
}
|
||||||
|
if err := rows.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return items, nil
|
||||||
|
}
|
||||||
|
|
||||||
const getWikisByIDs = `-- name: GetWikisByIDs :many
|
const getWikisByIDs = `-- name: GetWikisByIDs :many
|
||||||
SELECT id, project_id, title, slug, is_deleted, created_at, updated_at FROM wikis WHERE id = ANY($1::uuid[]) AND is_deleted = false
|
SELECT id, project_id, title, slug, is_deleted, created_at, updated_at FROM wikis WHERE id = ANY($1::uuid[]) AND is_deleted = false
|
||||||
`
|
`
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ type EntityRepository interface {
|
|||||||
Delete(ctx context.Context, id pgtype.UUID) error
|
Delete(ctx context.Context, id pgtype.UUID) error
|
||||||
DeleteByIDs(ctx context.Context, ids []pgtype.UUID) error
|
DeleteByIDs(ctx context.Context, ids []pgtype.UUID) error
|
||||||
GetByProjectID(ctx context.Context, projectID pgtype.UUID) ([]*models.EntityEntity, error)
|
GetByProjectID(ctx context.Context, projectID pgtype.UUID) ([]*models.EntityEntity, error)
|
||||||
|
GetEntityIDsByGeometryIDs(ctx context.Context, geometryIDs []string) (map[string][]string, error)
|
||||||
WithTx(tx pgx.Tx) EntityRepository
|
WithTx(tx pgx.Tx) EntityRepository
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -412,3 +413,62 @@ func (r *entityRepository) GetBySlugs(ctx context.Context, slugs []string) ([]*m
|
|||||||
|
|
||||||
return entities, nil
|
return entities, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *entityRepository) GetEntityIDsByGeometryIDs(ctx context.Context, geometryIDs []string) (map[string][]string, error) {
|
||||||
|
if len(geometryIDs) == 0 {
|
||||||
|
return make(map[string][]string), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
keys := make([]string, len(geometryIDs))
|
||||||
|
for i, id := range geometryIDs {
|
||||||
|
keys[i] = fmt.Sprintf("entity_geometries:geometry:%s", id)
|
||||||
|
}
|
||||||
|
|
||||||
|
raws := r.c.MGet(ctx, keys...)
|
||||||
|
result := make(map[string][]string)
|
||||||
|
var missingGeometryIDs []string
|
||||||
|
var missingPgIDs []pgtype.UUID
|
||||||
|
|
||||||
|
for i, b := range raws {
|
||||||
|
if len(b) > 0 {
|
||||||
|
var entityIDs []string
|
||||||
|
if err := json.Unmarshal(b, &entityIDs); err == nil {
|
||||||
|
result[geometryIDs[i]] = entityIDs
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
missingGeometryIDs = append(missingGeometryIDs, geometryIDs[i])
|
||||||
|
pgID, err := convert.StringToUUID(geometryIDs[i])
|
||||||
|
if err == nil {
|
||||||
|
missingPgIDs = append(missingPgIDs, pgID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(missingPgIDs) > 0 {
|
||||||
|
rows, err := r.q.GetEntityIDsByGeometryIDs(ctx, missingPgIDs)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
dbMap := make(map[string][]string)
|
||||||
|
for _, id := range missingGeometryIDs {
|
||||||
|
dbMap[id] = []string{}
|
||||||
|
}
|
||||||
|
for _, row := range rows {
|
||||||
|
gID := convert.UUIDToString(row.GeometryID)
|
||||||
|
eID := convert.UUIDToString(row.EntityID)
|
||||||
|
dbMap[gID] = append(dbMap[gID], eID)
|
||||||
|
}
|
||||||
|
|
||||||
|
missingToCache := make(map[string]any)
|
||||||
|
for gID, eIDs := range dbMap {
|
||||||
|
result[gID] = eIDs
|
||||||
|
missingToCache[fmt.Sprintf("entity_geometries:geometry:%s", gID)] = eIDs
|
||||||
|
}
|
||||||
|
if len(missingToCache) > 0 {
|
||||||
|
_ = r.c.MSet(ctx, missingToCache, constants.NormalCacheDuration)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ type WikiRepository interface {
|
|||||||
GetContentCountByWikiID(ctx context.Context, wikiID pgtype.UUID) (int64, error)
|
GetContentCountByWikiID(ctx context.Context, wikiID pgtype.UUID) (int64, error)
|
||||||
GetContentByID(ctx context.Context, id pgtype.UUID) (*models.WikiContentEntity, error)
|
GetContentByID(ctx context.Context, id pgtype.UUID) (*models.WikiContentEntity, error)
|
||||||
GetContentByIDs(ctx context.Context, ids []string) ([]*models.WikiContentEntity, error)
|
GetContentByIDs(ctx context.Context, ids []string) ([]*models.WikiContentEntity, error)
|
||||||
|
GetWikiIDsByEntityIDs(ctx context.Context, entityIDs []string) (map[string][]string, error)
|
||||||
WithTx(tx pgx.Tx) WikiRepository
|
WithTx(tx pgx.Tx) WikiRepository
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -638,3 +639,62 @@ func (r *wikiRepository) GetContentByID(ctx context.Context, id pgtype.UUID) (*m
|
|||||||
func (r *wikiRepository) GetContentByIDs(ctx context.Context, ids []string) ([]*models.WikiContentEntity, error) {
|
func (r *wikiRepository) GetContentByIDs(ctx context.Context, ids []string) ([]*models.WikiContentEntity, error) {
|
||||||
return r.getContentByIDsWithFallback(ctx, ids)
|
return r.getContentByIDsWithFallback(ctx, ids)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *wikiRepository) GetWikiIDsByEntityIDs(ctx context.Context, entityIDs []string) (map[string][]string, error) {
|
||||||
|
if len(entityIDs) == 0 {
|
||||||
|
return make(map[string][]string), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
keys := make([]string, len(entityIDs))
|
||||||
|
for i, id := range entityIDs {
|
||||||
|
keys[i] = fmt.Sprintf("entity_wikis:entity:%s", id)
|
||||||
|
}
|
||||||
|
|
||||||
|
raws := r.c.MGet(ctx, keys...)
|
||||||
|
result := make(map[string][]string)
|
||||||
|
var missingEntityIDs []string
|
||||||
|
var missingPgIDs []pgtype.UUID
|
||||||
|
|
||||||
|
for i, b := range raws {
|
||||||
|
if len(b) > 0 {
|
||||||
|
var wikiIDs []string
|
||||||
|
if err := json.Unmarshal(b, &wikiIDs); err == nil {
|
||||||
|
result[entityIDs[i]] = wikiIDs
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
missingEntityIDs = append(missingEntityIDs, entityIDs[i])
|
||||||
|
pgID, err := convert.StringToUUID(entityIDs[i])
|
||||||
|
if err == nil {
|
||||||
|
missingPgIDs = append(missingPgIDs, pgID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(missingPgIDs) > 0 {
|
||||||
|
rows, err := r.q.GetWikiIDsByEntityIDs(ctx, missingPgIDs)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
dbMap := make(map[string][]string)
|
||||||
|
for _, id := range missingEntityIDs {
|
||||||
|
dbMap[id] = []string{}
|
||||||
|
}
|
||||||
|
for _, row := range rows {
|
||||||
|
eID := convert.UUIDToString(row.EntityID)
|
||||||
|
wID := convert.UUIDToString(row.WikiID)
|
||||||
|
dbMap[eID] = append(dbMap[eID], wID)
|
||||||
|
}
|
||||||
|
|
||||||
|
missingToCache := make(map[string]any)
|
||||||
|
for eID, wIDs := range dbMap {
|
||||||
|
result[eID] = wIDs
|
||||||
|
missingToCache[fmt.Sprintf("entity_wikis:entity:%s", eID)] = wIDs
|
||||||
|
}
|
||||||
|
if len(missingToCache) > 0 {
|
||||||
|
_ = r.c.MSet(ctx, missingToCache, constants.NormalCacheDuration)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package routes
|
||||||
|
|
||||||
|
import (
|
||||||
|
"history-api/internal/controllers"
|
||||||
|
|
||||||
|
"github.com/gofiber/fiber/v3"
|
||||||
|
)
|
||||||
|
|
||||||
|
func RelationRoutes(router fiber.Router, wikiController *controllers.WikiController, entityController *controllers.EntityController) {
|
||||||
|
relation := router.Group("/relations")
|
||||||
|
relation.Get("/wikis-by-entities", wikiController.GetWikisByEntityIDs)
|
||||||
|
relation.Get("/entities-by-geometries", entityController.GetEntitiesByGeometryIDs)
|
||||||
|
relation.Get("/wiki-contents/preview", wikiController.GetWikiContentsPreviewByIDs)
|
||||||
|
}
|
||||||
@@ -14,4 +14,3 @@ func WikiRoutes(router fiber.Router, wikiController *controllers.WikiController)
|
|||||||
wiki.Get("/content/:id", wikiController.GetWikiContentById)
|
wiki.Get("/content/:id", wikiController.GetWikiContentById)
|
||||||
wiki.Get("/:id", wikiController.GetWikiById)
|
wiki.Get("/:id", wikiController.GetWikiById)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ type EntityService interface {
|
|||||||
GetEntityBySlug(ctx context.Context, slug string) (*response.EntityResponse, *fiber.Error)
|
GetEntityBySlug(ctx context.Context, slug string) (*response.EntityResponse, *fiber.Error)
|
||||||
IsExistEntitySlug(ctx context.Context, slug string) (bool, *fiber.Error)
|
IsExistEntitySlug(ctx context.Context, slug string) (bool, *fiber.Error)
|
||||||
SearchEntities(ctx context.Context, req *request.SearchEntityDto) ([]*response.EntityResponse, *fiber.Error)
|
SearchEntities(ctx context.Context, req *request.SearchEntityDto) ([]*response.EntityResponse, *fiber.Error)
|
||||||
|
GetEntitiesByGeometryIDs(ctx context.Context, req *request.GetEntitiesByGeometryIDsDto) (map[string][]*response.EntityResponse, *fiber.Error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type entityService struct {
|
type entityService struct {
|
||||||
@@ -101,3 +102,45 @@ func (s *entityService) SearchEntities(ctx context.Context, req *request.SearchE
|
|||||||
|
|
||||||
return models.EntitiesEntityToResponse(entities), nil
|
return models.EntitiesEntityToResponse(entities), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *entityService) GetEntitiesByGeometryIDs(ctx context.Context, req *request.GetEntitiesByGeometryIDsDto) (map[string][]*response.EntityResponse, *fiber.Error) {
|
||||||
|
mapping, err := s.entityRepo.GetEntityIDsByGeometryIDs(ctx, req.GeometryIDs)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch entity IDs by geometry IDs")
|
||||||
|
}
|
||||||
|
|
||||||
|
entityIDMap := make(map[string]struct{})
|
||||||
|
var allEntityIDs []string
|
||||||
|
for _, eIDs := range mapping {
|
||||||
|
for _, eID := range eIDs {
|
||||||
|
if _, ok := entityIDMap[eID]; !ok {
|
||||||
|
entityIDMap[eID] = struct{}{}
|
||||||
|
allEntityIDs = append(allEntityIDs, eID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
entities, err := s.entityRepo.GetByIDs(ctx, allEntityIDs)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch entities")
|
||||||
|
}
|
||||||
|
|
||||||
|
entitiesByID := make(map[string]*models.EntityEntity)
|
||||||
|
for _, e := range entities {
|
||||||
|
entitiesByID[e.ID] = e
|
||||||
|
}
|
||||||
|
|
||||||
|
result := make(map[string][]*response.EntityResponse)
|
||||||
|
for _, idStr := range req.GeometryIDs {
|
||||||
|
result[idStr] = make([]*response.EntityResponse, 0)
|
||||||
|
if eIDs, exists := mapping[idStr]; exists {
|
||||||
|
for _, eID := range eIDs {
|
||||||
|
if e, found := entitiesByID[eID]; found {
|
||||||
|
result[idStr] = append(result[idStr], e.ToResponse())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ type WikiService interface {
|
|||||||
IsExistWikiSlug(ctx context.Context, slug string) (bool, *fiber.Error)
|
IsExistWikiSlug(ctx context.Context, slug string) (bool, *fiber.Error)
|
||||||
SearchWikis(ctx context.Context, req *request.SearchWikiDto) ([]*response.WikiResponse, *fiber.Error)
|
SearchWikis(ctx context.Context, req *request.SearchWikiDto) ([]*response.WikiResponse, *fiber.Error)
|
||||||
GetWikiContentByID(ctx context.Context, id string) (*response.WikiContentResponse, *fiber.Error)
|
GetWikiContentByID(ctx context.Context, id string) (*response.WikiContentResponse, *fiber.Error)
|
||||||
|
GetWikisByEntityIDs(ctx context.Context, req *request.GetWikisByEntityIDsDto) (map[string][]*response.WikiResponse, *fiber.Error)
|
||||||
|
GetWikiContentsPreviewByIDs(ctx context.Context, req *request.GetWikiContentsPreviewDto) ([]*response.WikiContentPreviewResponse, *fiber.Error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type wikiService struct {
|
type wikiService struct {
|
||||||
@@ -128,3 +130,63 @@ func (s *wikiService) GetWikiContentByID(ctx context.Context, id string) (*respo
|
|||||||
CreatedAt: content.CreatedAt,
|
CreatedAt: content.CreatedAt,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *wikiService) GetWikisByEntityIDs(ctx context.Context, req *request.GetWikisByEntityIDsDto) (map[string][]*response.WikiResponse, *fiber.Error) {
|
||||||
|
mapping, err := s.wikiRepo.GetWikiIDsByEntityIDs(ctx, req.EntityIDs)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch wiki IDs by entity IDs")
|
||||||
|
}
|
||||||
|
|
||||||
|
wikiIDMap := make(map[string]struct{})
|
||||||
|
var allWikiIDs []string
|
||||||
|
for _, wIDs := range mapping {
|
||||||
|
for _, wID := range wIDs {
|
||||||
|
if _, ok := wikiIDMap[wID]; !ok {
|
||||||
|
wikiIDMap[wID] = struct{}{}
|
||||||
|
allWikiIDs = append(allWikiIDs, wID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wikis, err := s.wikiRepo.GetByIDs(ctx, allWikiIDs)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch wikis")
|
||||||
|
}
|
||||||
|
|
||||||
|
wikisByID := make(map[string]*models.WikiEntity)
|
||||||
|
for _, w := range wikis {
|
||||||
|
wikisByID[w.ID] = w
|
||||||
|
}
|
||||||
|
|
||||||
|
result := make(map[string][]*response.WikiResponse)
|
||||||
|
for _, idStr := range req.EntityIDs {
|
||||||
|
result[idStr] = make([]*response.WikiResponse, 0)
|
||||||
|
if wIDs, exists := mapping[idStr]; exists {
|
||||||
|
for _, wID := range wIDs {
|
||||||
|
if w, found := wikisByID[wID]; found {
|
||||||
|
result[idStr] = append(result[idStr], w.ToResponse())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *wikiService) GetWikiContentsPreviewByIDs(ctx context.Context, req *request.GetWikiContentsPreviewDto) ([]*response.WikiContentPreviewResponse, *fiber.Error) {
|
||||||
|
contents, err := s.wikiRepo.GetContentByIDs(ctx, req.IDs)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch wiki contents")
|
||||||
|
}
|
||||||
|
|
||||||
|
var results []*response.WikiContentPreviewResponse
|
||||||
|
for _, c := range contents {
|
||||||
|
results = append(results, &response.WikiContentPreviewResponse{
|
||||||
|
ID: c.ID,
|
||||||
|
Preview: c.Preview,
|
||||||
|
CreatedAt: c.CreatedAt,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return results, nil
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user