services

package
v0.0.0-...-0fec8e7 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 21, 2025 License: MIT Imports: 36 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type APIService

type APIService interface {
	CreateProject(ctx *fiber.Ctx) error
	UpdateProject(ctx *fiber.Ctx) error
	DeleteProject(ctx *fiber.Ctx) error
	CountProjectSize(ctx *fiber.Ctx) error
	CountMonthlyEvents(ctx *fiber.Ctx) error
	LastDataRetrieved(c *fiber.Ctx) error
	LiveEvents(ctx *fiber.Ctx) error
	LiveEventDetail(ctx *fiber.Ctx) error
	GetEventSummary(c *fiber.Ctx) error
	GetEventSummaryDetail(c *fiber.Ctx) error
	StartDownloadEvent(c *fiber.Ctx) error
	FinishDownloadEvent(c *fiber.Ctx) error
	JSONWeeklyEventChart(c *fiber.Ctx) error
	JSONEventTypeChart(c *fiber.Ctx) error
	JSONEventLabelChart(c *fiber.Ctx) error
	CreateAPIKey(ctx *fiber.Ctx) error
	DeleteAPIKey(ctx *fiber.Ctx) error
	GetProjectSummary(c *fiber.Ctx) error
	StreamAgentSummary(c *fiber.Ctx) error
}

type APIServiceImpl

type APIServiceImpl struct {
	ProjectService  ProjectService
	EventService    EventService
	DownloadService DownloadService
	CacheService    CacheService
	KeyService      KeyService
	AggrService     AggrService
}

func InitAPIService

func InitAPIService(
	projectService ProjectService,
	eventService EventService,
	downloadService DownloadService,
	cacheService CacheService,
	keyService KeyService,
	aggrService AggrService,
) APIServiceImpl

func (*APIServiceImpl) CountMonthlyEvents

func (s *APIServiceImpl) CountMonthlyEvents(c *fiber.Ctx) error

func (*APIServiceImpl) CountProjectSize

func (s *APIServiceImpl) CountProjectSize(c *fiber.Ctx) error

func (*APIServiceImpl) CreateAPIKey

func (s *APIServiceImpl) CreateAPIKey(c *fiber.Ctx) error

func (*APIServiceImpl) CreateProject

func (s *APIServiceImpl) CreateProject(c *fiber.Ctx) error

func (*APIServiceImpl) DeleteAPIKey

func (s *APIServiceImpl) DeleteAPIKey(c *fiber.Ctx) error

func (*APIServiceImpl) DeleteProject

func (s *APIServiceImpl) DeleteProject(c *fiber.Ctx) error

func (*APIServiceImpl) FinishDownloadEvent

func (s *APIServiceImpl) FinishDownloadEvent(c *fiber.Ctx) error

func (*APIServiceImpl) GetEventSummary

func (s *APIServiceImpl) GetEventSummary(c *fiber.Ctx) error

func (*APIServiceImpl) GetEventSummaryDetail

func (s *APIServiceImpl) GetEventSummaryDetail(c *fiber.Ctx) error

func (*APIServiceImpl) GetProjectSummary

func (s *APIServiceImpl) GetProjectSummary(c *fiber.Ctx) error

func (*APIServiceImpl) JSONEventLabelChart

func (s *APIServiceImpl) JSONEventLabelChart(c *fiber.Ctx) error

func (*APIServiceImpl) JSONEventTypeChart

func (s *APIServiceImpl) JSONEventTypeChart(c *fiber.Ctx) error

func (*APIServiceImpl) JSONWeeklyEventChart

func (s *APIServiceImpl) JSONWeeklyEventChart(c *fiber.Ctx) error

func (*APIServiceImpl) LastDataRetrieved

func (s *APIServiceImpl) LastDataRetrieved(c *fiber.Ctx) error

func (*APIServiceImpl) LiveEventDetail

func (s *APIServiceImpl) LiveEventDetail(c *fiber.Ctx) error

func (*APIServiceImpl) LiveEvents

func (s *APIServiceImpl) LiveEvents(c *fiber.Ctx) error

func (*APIServiceImpl) StartDownloadEvent

func (s *APIServiceImpl) StartDownloadEvent(c *fiber.Ctx) error

func (*APIServiceImpl) StreamAgentSummary

func (s *APIServiceImpl) StreamAgentSummary(c *fiber.Ctx) error

func (*APIServiceImpl) UpdateAPIKey

func (s *APIServiceImpl) UpdateAPIKey(c *fiber.Ctx) error

func (*APIServiceImpl) UpdateProject

func (s *APIServiceImpl) UpdateProject(c *fiber.Ctx) error

type AggrService

type AggrService interface {
	GetBriefSummary(ctx context.Context, projectID uuid.UUID, userID uuid.UUID) (*gen.GetBriefAggrRow, error)
	GetDetailSummary(ctx context.Context, projectID uuid.UUID, userID uuid.UUID) (*entities.EventDetail, error)
	SaveProjectAggr(ctx context.Context, projectID uuid.UUID, userID uuid.UUID) error
	FindProjectAggr(ctx context.Context, projectID uuid.UUID, userID uuid.UUID, limit int32) ([]entities.ProjectAggr, error)
}

type AggrServiceImpl

type AggrServiceImpl struct {
	UtilService UtilService
	AggrRepo    repositories.AggrRepo
	ProjectRepo repositories.ProjectRepo
}

func InitAggrService

func InitAggrService(
	utilService UtilService,
	aggrRepo repositories.AggrRepo,
	projectRepo repositories.ProjectRepo,
) AggrServiceImpl

func (*AggrServiceImpl) FindProjectAggr

func (s *AggrServiceImpl) FindProjectAggr(ctx context.Context, projectID uuid.UUID, userID uuid.UUID, limit int32) ([]entities.ProjectAggr, error)

func (*AggrServiceImpl) GetBriefSummary

func (s *AggrServiceImpl) GetBriefSummary(ctx context.Context, projectID uuid.UUID, userID uuid.UUID) (*gen.GetBriefAggrRow, error)

func (*AggrServiceImpl) GetDetailSummary

func (s *AggrServiceImpl) GetDetailSummary(ctx context.Context, projectID uuid.UUID, userID uuid.UUID) (*entities.EventDetail, error)

func (*AggrServiceImpl) SaveProjectAggr

func (s *AggrServiceImpl) SaveProjectAggr(ctx context.Context, projectID uuid.UUID, userID uuid.UUID) error

type AuthService

type AuthService interface {
	RegisterFirstUser(ctx *fiber.Ctx) error
	Login(ctx *fiber.Ctx) error
	Logout(ctx *fiber.Ctx) error
}

type AuthServiceImpl

type AuthServiceImpl struct {
	UtilService  UtilService
	UserService  UserService
	SessionStore *session.Store
}

func InitAuthService

func InitAuthService(
	utilService UtilService,
	userService UserService,
	sessionStore *session.Store,
) AuthServiceImpl

func (*AuthServiceImpl) Login

func (s *AuthServiceImpl) Login(c *fiber.Ctx) error

func (*AuthServiceImpl) Logout

func (s *AuthServiceImpl) Logout(c *fiber.Ctx) error

func (*AuthServiceImpl) RegisterFirstUser

func (s *AuthServiceImpl) RegisterFirstUser(c *fiber.Ctx) error

type CacheService

type CacheService interface {
	GetCache(key string) ([]byte, error)
	SetCache(key string, value []byte, exp time.Duration) error
	InvalidateCaches(keys []string) error
}

type CacheServiceImpl

type CacheServiceImpl struct {
	RedisCon *redis.Storage
}

func InitCacheService

func InitCacheService(redisCon *redis.Storage) CacheServiceImpl

func (*CacheServiceImpl) GetCache

func (s *CacheServiceImpl) GetCache(key string) ([]byte, error)

func (*CacheServiceImpl) InvalidateCaches

func (s *CacheServiceImpl) InvalidateCaches(keys []string) error

func (*CacheServiceImpl) SetCache

func (s *CacheServiceImpl) SetCache(key string, value []byte, exp time.Duration) error

type DownloadService

type DownloadService interface {
	DownloadEventData(ctx context.Context, projectID uuid.UUID, userID uuid.UUID, interval int32) ([]string, [][]string, error)
	WriteCSV(wFile *os.File, header []string, body [][]string) error
	WriteXLSX(wFile *os.File, header []string, body [][]string) error
	WriteJSON(wFile *os.File, header []string, body [][]string) error
	WriteHTML(wFile *os.File, header []string, body [][]string) error
	WritePDF(wFile *os.File, header []string, body [][]string) error
}

type DownloadServiceImpl

type DownloadServiceImpl struct {
	UtilService UtilService
	Repo        repositories.DownloadRepo
}

func InitDownloadService

func InitDownloadService(utilService UtilService, repository repositories.DownloadRepo) DownloadServiceImpl

func (*DownloadServiceImpl) DownloadEventData

func (s *DownloadServiceImpl) DownloadEventData(ctx context.Context, projectID uuid.UUID, userID uuid.UUID, interval int32) ([]string, [][]string, error)

func (*DownloadServiceImpl) WriteCSV

func (s *DownloadServiceImpl) WriteCSV(wFile *os.File, header []string, body [][]string) error

func (*DownloadServiceImpl) WriteHTML

func (s *DownloadServiceImpl) WriteHTML(wFile *os.File, header []string, body [][]string) error

func (*DownloadServiceImpl) WriteHTMLBuilder

func (s *DownloadServiceImpl) WriteHTMLBuilder(header []string, body [][]string) string

func (*DownloadServiceImpl) WriteJSON

func (s *DownloadServiceImpl) WriteJSON(wFile *os.File, header []string, body [][]string) error

func (*DownloadServiceImpl) WritePDF

func (s *DownloadServiceImpl) WritePDF(wFile *os.File, header []string, body [][]string) error

func (*DownloadServiceImpl) WriteXLSX

func (s *DownloadServiceImpl) WriteXLSX(wFile *os.File, header []string, body [][]string) error

type EventService

type EventService interface {
	CreateEvent(c *fiber.Ctx) error
	GetEvents(c *fiber.Ctx) error
	GetLiveEvents(ctx context.Context, userID uuid.UUID) ([]gen.GetLiveEventsRow, error)
	GetLiveEventDetail(ctx context.Context, projectID uuid.UUID, userID uuid.UUID, strategy string, limit int32) ([]gen.GetLiveEventsDetailRow, error)
	GetWeeklyEventsChart(ctx context.Context, projectID uuid.UUID, userID uuid.UUID) (*entities.EventSummaryChart, error)
	GetEventTypeChart(ctx context.Context, projectID uuid.UUID, userID uuid.UUID) ([]gen.GetPercentageEventsTypeRow, error)
	GetEventLabelChart(ctx context.Context, projectID uuid.UUID, userID uuid.UUID) ([]gen.GetPercentageEventsLabelRow, error)
	CountUserMonthlyEvents(ctx context.Context, userID uuid.UUID) (int64, error)
}

type EventServiceImpl

type EventServiceImpl struct {
	UtilService  UtilService
	CacheService CacheService
	AggrService  AggrService
	WorkerPool   WorkerPool
	Repo         repositories.EventRepo
	ProjectRepo  repositories.ProjectRepo
}

func InitEventService

func InitEventService(
	utilService UtilService,
	cacheService CacheService,
	aggrService AggrService,
	workerPool WorkerPool,
	repo repositories.EventRepo,
	projectRepo repositories.ProjectRepo,
) EventServiceImpl

func (*EventServiceImpl) CountUserMonthlyEvents

func (s *EventServiceImpl) CountUserMonthlyEvents(ctx context.Context, userID uuid.UUID) (int64, error)

func (*EventServiceImpl) CreateEvent

func (s *EventServiceImpl) CreateEvent(c *fiber.Ctx) error

func (*EventServiceImpl) GetEventLabelChart

func (s *EventServiceImpl) GetEventLabelChart(ctx context.Context, projectID uuid.UUID, userID uuid.UUID) ([]gen.GetPercentageEventsLabelRow, error)

func (*EventServiceImpl) GetEventTypeChart

func (s *EventServiceImpl) GetEventTypeChart(ctx context.Context, projectID uuid.UUID, userID uuid.UUID) ([]gen.GetPercentageEventsTypeRow, error)

func (*EventServiceImpl) GetEvents

func (s *EventServiceImpl) GetEvents(c *fiber.Ctx) error

func (*EventServiceImpl) GetLiveEventDetail

func (s *EventServiceImpl) GetLiveEventDetail(ctx context.Context, projectID uuid.UUID, userID uuid.UUID, isNFetch string, limit int32) ([]gen.GetLiveEventsDetailRow, error)

func (*EventServiceImpl) GetLiveEvents

func (s *EventServiceImpl) GetLiveEvents(ctx context.Context, userID uuid.UUID) ([]gen.GetLiveEventsRow, error)

func (*EventServiceImpl) GetWeeklyEventsChart

func (s *EventServiceImpl) GetWeeklyEventsChart(ctx context.Context, projectID uuid.UUID, userID uuid.UUID) (*entities.EventSummaryChart, error)

type KeyService

type KeyService interface {
	CreateAPIKey(ctx context.Context, name string, userID uuid.UUID) (*gen.CreateAPIKeyRow, error)
	GetAllKeys(ctx context.Context, userID uuid.UUID) ([]gen.FindAllAPIKeysRow, error)
	DeleteKey(ctx context.Context, userID uuid.UUID, keyID int) error
}

type KeyServiceImpl

type KeyServiceImpl struct {
	UtilService UtilService
	Repo        repositories.KeyRepo
}

func InitKeyService

func InitKeyService(
	utilService UtilService,
	repo repositories.KeyRepo,
) KeyServiceImpl

func (*KeyServiceImpl) CreateAPIKey

func (s *KeyServiceImpl) CreateAPIKey(ctx context.Context, name string, userID uuid.UUID) (*gen.CreateAPIKeyRow, error)

func (*KeyServiceImpl) DeleteKey

func (s *KeyServiceImpl) DeleteKey(ctx context.Context, userID uuid.UUID, keyID int) error

func (*KeyServiceImpl) GetAllKeys

func (s *KeyServiceImpl) GetAllKeys(ctx context.Context, userID uuid.UUID) ([]gen.FindAllAPIKeysRow, error)

type ProjectService

type ProjectService interface {
	CreateProject(ctx context.Context, name string, desc string, url string, userID uuid.UUID) (*gen.CreateProjectRow, error)
	UpdateProject(ctx context.Context, name string, desc string, url string, projectID uuid.UUID, userID uuid.UUID) error
	GetProjectByID(ctx context.Context, projectID uuid.UUID, userID uuid.UUID) (*gen.FindProjectByIDRow, error)
	GetAllProjects(ctx context.Context, userID uuid.UUID) ([]gen.FindAllProjectsRow, error)
	GetProjectCount(ctx context.Context, userID uuid.UUID) (int64, error)
	DeleteProject(ctx context.Context, userID uuid.UUID, projectID uuid.UUID) error
	CountProjectSize(ctx context.Context, projectID uuid.UUID, userID uuid.UUID) (int64, error)
	LastProjectDataReceived(ctx context.Context, projectID uuid.UUID, userID uuid.UUID) (*time.Time, error)
}

type ProjectServiceImpl

type ProjectServiceImpl struct {
	EventService EventService
	UtilService  UtilService
	Repo         repositories.ProjectRepo
}

func InitProjectService

func InitProjectService(repo repositories.ProjectRepo, eventService EventService, utilService UtilService) ProjectServiceImpl

func (*ProjectServiceImpl) CountProjectSize

func (s *ProjectServiceImpl) CountProjectSize(ctx context.Context, projectID uuid.UUID, userID uuid.UUID) (int64, error)

func (*ProjectServiceImpl) CreateProject

func (s *ProjectServiceImpl) CreateProject(ctx context.Context, name string, desc string, url string, userID uuid.UUID) (*gen.CreateProjectRow, error)

func (*ProjectServiceImpl) DeleteProject

func (s *ProjectServiceImpl) DeleteProject(ctx context.Context, userID uuid.UUID, projectID uuid.UUID) error

func (*ProjectServiceImpl) GetAllProjects

func (s *ProjectServiceImpl) GetAllProjects(ctx context.Context, userID uuid.UUID) ([]gen.FindAllProjectsRow, error)

func (*ProjectServiceImpl) GetProjectByID

func (s *ProjectServiceImpl) GetProjectByID(ctx context.Context, projectID uuid.UUID, userID uuid.UUID) (*gen.FindProjectByIDRow, error)

func (*ProjectServiceImpl) GetProjectCount

func (s *ProjectServiceImpl) GetProjectCount(ctx context.Context, userID uuid.UUID) (int64, error)

func (*ProjectServiceImpl) LastProjectDataReceived

func (s *ProjectServiceImpl) LastProjectDataReceived(ctx context.Context, projectID uuid.UUID, userID uuid.UUID) (*time.Time, error)

func (*ProjectServiceImpl) UpdateProject

func (s *ProjectServiceImpl) UpdateProject(ctx context.Context, name string, desc string, url string, projectID uuid.UUID, userID uuid.UUID) error

type UserService

type UserService interface {
	FindByEmail(email string) (*gen.FindUserByEmailRow, error)
	FindByEmailWithHash(email string) (*gen.FindUserByEmailWithHashRow, error)
	FindByID(userID uuid.UUID) (*gen.FindUserByIDRow, error)
	FindByPublicKey(key string) (*gen.FindUserByPublicKeyRow, error)
	FindByPrivateKey(key string) (*gen.FindUserByPrivateKeyRow, error)
	CheckAdminExist() (bool, error)
	GetPublicKey(userID uuid.UUID) (string, error)
	CreateUser(payload *gen.CreateUserParams) (*gen.CreateUserRow, error)
}

type UserServiceImpl

type UserServiceImpl struct {
	UtilService UtilService
	Repo        repositories.UserRepo
}

func InitUserService

func InitUserService(utilService UtilService, repo repositories.UserRepo) UserServiceImpl

func (*UserServiceImpl) CheckAdminExist

func (s *UserServiceImpl) CheckAdminExist() (bool, error)

func (*UserServiceImpl) CreateUser

func (s *UserServiceImpl) CreateUser(payload *gen.CreateUserParams) (*gen.CreateUserRow, error)

func (*UserServiceImpl) FindByEmail

func (s *UserServiceImpl) FindByEmail(email string) (*gen.FindUserByEmailRow, error)

func (*UserServiceImpl) FindByEmailWithHash

func (s *UserServiceImpl) FindByEmailWithHash(email string) (*gen.FindUserByEmailWithHashRow, error)

func (*UserServiceImpl) FindByID

func (s *UserServiceImpl) FindByID(userID uuid.UUID) (*gen.FindUserByIDRow, error)

func (*UserServiceImpl) FindByPrivateKey

func (s *UserServiceImpl) FindByPrivateKey(key string) (*gen.FindUserByPrivateKeyRow, error)

func (*UserServiceImpl) FindByPublicKey

func (s *UserServiceImpl) FindByPublicKey(key string) (*gen.FindUserByPublicKeyRow, error)

func (*UserServiceImpl) GetPublicKey

func (s *UserServiceImpl) GetPublicKey(userID uuid.UUID) (string, error)

type UtilService

type UtilService interface {
	GenerateRandomID(length int) string
	ValidateInput(payload any) string
	GenerateHash(password string) string
	CompareHash(password string, hash string) bool
	ParseIP(str string) *netip.Addr
	ParseTimestamp(str string) time.Time
	LookupIP(ipStr string) *geoip2.City
	LookupAlphabetFromIdx(index int) string
	ByteToJSON(v []byte) interface{}
}

type UtilServiceImpl

type UtilServiceImpl struct {
	Validate *validator.Validate
	IPRepo   repositories.IPDBRepo
}

func InitUtilService

func InitUtilService(
	validate *validator.Validate,
	ipRepo repositories.IPDBRepo,
) UtilServiceImpl

func (*UtilServiceImpl) ByteToJSON

func (s *UtilServiceImpl) ByteToJSON(v []byte) interface{}

func (*UtilServiceImpl) CompareHash

func (s *UtilServiceImpl) CompareHash(password string, hash string) bool

func (*UtilServiceImpl) GenerateHash

func (s *UtilServiceImpl) GenerateHash(password string) string

func (*UtilServiceImpl) GenerateRandomID

func (s *UtilServiceImpl) GenerateRandomID(length int) string

func (*UtilServiceImpl) LookupAlphabetFromIdx

func (s *UtilServiceImpl) LookupAlphabetFromIdx(index int) string

func (*UtilServiceImpl) LookupIP

func (s *UtilServiceImpl) LookupIP(ipStr string) *geoip2.City

func (*UtilServiceImpl) ParseIP

func (s *UtilServiceImpl) ParseIP(str string) *netip.Addr

func (*UtilServiceImpl) ParseTimestamp

func (s *UtilServiceImpl) ParseTimestamp(str string) time.Time

func (*UtilServiceImpl) ValidateInput

func (s *UtilServiceImpl) ValidateInput(payload any) string

type WebService

type WebService interface {
	SendLandingPage(ctx *fiber.Ctx) error
	SendLoginPage(ctx *fiber.Ctx) error
	SendCreateFirstTimeUserPage(ctx *fiber.Ctx) error
	SendDashboardPage(ctx *fiber.Ctx) error
	SendPricingPage(ctx *fiber.Ctx) error
	SendEventsPage(ctx *fiber.Ctx) error
	SendEventDetailPage(ctx *fiber.Ctx) error
	SendProjectsPage(ctx *fiber.Ctx) error
	SendAPIKeysPage(ctx *fiber.Ctx) error
	SendTOSPage(ctx *fiber.Ctx) error
	SendAuthRedirectPage(ctx *fiber.Ctx) error
}

type WebServiceImpl

type WebServiceImpl struct {
	UserService    UserService
	ProjectService ProjectService
	EventService   EventService
	KeyService     KeyService
	AggrService    AggrService
}

func InitWebService

func InitWebService(
	userService UserService,
	projectService ProjectService,
	eventService EventService,
	keyService KeyService,
	aggrService AggrService,
) WebServiceImpl

func (*WebServiceImpl) SendAPIKeysPage

func (s *WebServiceImpl) SendAPIKeysPage(c *fiber.Ctx) error

func (*WebServiceImpl) SendAuthRedirectPage

func (s *WebServiceImpl) SendAuthRedirectPage(c *fiber.Ctx) error

func (*WebServiceImpl) SendCreateFirstTimeUserPage

func (s *WebServiceImpl) SendCreateFirstTimeUserPage(c *fiber.Ctx) error

func (*WebServiceImpl) SendDashboardPage

func (s *WebServiceImpl) SendDashboardPage(c *fiber.Ctx) error

func (*WebServiceImpl) SendEventDetailPage

func (s *WebServiceImpl) SendEventDetailPage(c *fiber.Ctx) error

func (*WebServiceImpl) SendEventsPage

func (s *WebServiceImpl) SendEventsPage(c *fiber.Ctx) error

func (*WebServiceImpl) SendLandingPage

func (s *WebServiceImpl) SendLandingPage(c *fiber.Ctx) error

func (*WebServiceImpl) SendLoginPage

func (s *WebServiceImpl) SendLoginPage(c *fiber.Ctx) error

func (*WebServiceImpl) SendPricingPage

func (s *WebServiceImpl) SendPricingPage(c *fiber.Ctx) error

func (*WebServiceImpl) SendProjectsPage

func (s *WebServiceImpl) SendProjectsPage(c *fiber.Ctx) error

func (*WebServiceImpl) SendTOSPage

func (s *WebServiceImpl) SendTOSPage(c *fiber.Ctx) error

type WorkerJob

type WorkerJob struct {
	Timestamp time.Time // When the job was created
	UserID    uuid.UUID // Identifier
	ProjectID uuid.UUID // Identifier
	Callback  func()    // Callback to be executed when the job is called
}

WorkerJob represents a job to be processed by the worker pool. It includes metadata (UserID, ProjectID, Timestamp) and a Callback function that contains the actual work to be performed.

type WorkerPool

type WorkerPool struct {
	// contains filtered or unexported fields
}

WorkerPool manages a pool of workers to process jobs asynchronously. It includes a buffered channel for incoming jobs and a configurable pool size.

func InitWorkerPool

func InitWorkerPool(poolCount int, bufferSize int) *WorkerPool

func (*WorkerPool) StartWorker

func (wp *WorkerPool) StartWorker(ctx context.Context)

StartWorker starts the worker pool and spawns worker goroutines. Each worker processes jobs with a throttling mechanism to ensure jobs for the same UserID and ProjectID are not processed more frequently than every 2 seconds. ctx: Context for cancellation and graceful shutdown.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL