Initial commit: Open sourcing all of the Maple Open Technologies code.
This commit is contained in:
commit
755d54a99d
2010 changed files with 448675 additions and 0 deletions
44
cloud/maplepress-backend/internal/domain/page/interface.go
Normal file
44
cloud/maplepress-backend/internal/domain/page/interface.go
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
// File Path: monorepo/cloud/maplepress-backend/internal/domain/page/interface.go
|
||||
package page
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/gocql/gocql"
|
||||
)
|
||||
|
||||
// Repository defines the interface for page data operations
|
||||
type Repository interface {
|
||||
// Create inserts a new page
|
||||
Create(ctx context.Context, page *Page) error
|
||||
|
||||
// Update updates an existing page
|
||||
Update(ctx context.Context, page *Page) error
|
||||
|
||||
// Upsert creates or updates a page
|
||||
Upsert(ctx context.Context, page *Page) error
|
||||
|
||||
// GetByID retrieves a page by site_id and page_id
|
||||
GetByID(ctx context.Context, siteID gocql.UUID, pageID string) (*Page, error)
|
||||
|
||||
// GetBySiteID retrieves all pages for a site
|
||||
GetBySiteID(ctx context.Context, siteID gocql.UUID) ([]*Page, error)
|
||||
|
||||
// GetBySiteIDPaginated retrieves pages for a site with pagination
|
||||
GetBySiteIDPaginated(ctx context.Context, siteID gocql.UUID, limit int, pageState []byte) ([]*Page, []byte, error)
|
||||
|
||||
// Delete deletes a page
|
||||
Delete(ctx context.Context, siteID gocql.UUID, pageID string) error
|
||||
|
||||
// DeleteBySiteID deletes all pages for a site
|
||||
DeleteBySiteID(ctx context.Context, siteID gocql.UUID) error
|
||||
|
||||
// DeleteMultiple deletes multiple pages by their IDs
|
||||
DeleteMultiple(ctx context.Context, siteID gocql.UUID, pageIDs []string) error
|
||||
|
||||
// CountBySiteID counts pages for a site
|
||||
CountBySiteID(ctx context.Context, siteID gocql.UUID) (int64, error)
|
||||
|
||||
// Exists checks if a page exists
|
||||
Exists(ctx context.Context, siteID gocql.UUID, pageID string) (bool, error)
|
||||
}
|
||||
132
cloud/maplepress-backend/internal/domain/page/page.go
Normal file
132
cloud/maplepress-backend/internal/domain/page/page.go
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
// File Path: monorepo/cloud/maplepress-backend/internal/domain/page/page.go
|
||||
package page
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/gocql/gocql"
|
||||
)
|
||||
|
||||
// Page represents a WordPress page/post indexed in the system
|
||||
type Page struct {
|
||||
// Identity
|
||||
SiteID gocql.UUID `json:"site_id"` // Partition key
|
||||
PageID string `json:"page_id"` // Clustering key (WordPress page ID)
|
||||
TenantID gocql.UUID `json:"tenant_id"` // For additional isolation
|
||||
|
||||
// Content
|
||||
Title string `json:"title"`
|
||||
Content string `json:"content"` // HTML stripped
|
||||
Excerpt string `json:"excerpt"` // Summary
|
||||
|
||||
URL string `json:"url"` // Canonical URL
|
||||
|
||||
// Metadata
|
||||
Status string `json:"status"` // publish, draft, trash
|
||||
PostType string `json:"post_type"` // page, post
|
||||
Author string `json:"author"`
|
||||
|
||||
// Timestamps
|
||||
PublishedAt time.Time `json:"published_at"`
|
||||
ModifiedAt time.Time `json:"modified_at"`
|
||||
IndexedAt time.Time `json:"indexed_at"` // When we indexed it
|
||||
|
||||
// Search
|
||||
MeilisearchDocID string `json:"meilisearch_doc_id"` // ID in Meilisearch index
|
||||
|
||||
// Audit
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
|
||||
// CWE-359: IP address tracking for GDPR compliance (90-day expiration)
|
||||
CreatedFromIPAddress string `json:"-"` // Encrypted IP address, never exposed in JSON
|
||||
CreatedFromIPTimestamp time.Time `json:"-"` // For 90-day expiration tracking
|
||||
ModifiedFromIPAddress string `json:"-"` // Encrypted IP address, never exposed in JSON
|
||||
ModifiedFromIPTimestamp time.Time `json:"-"` // For 90-day expiration tracking
|
||||
}
|
||||
|
||||
// Status constants
|
||||
const (
|
||||
StatusPublish = "publish"
|
||||
StatusDraft = "draft"
|
||||
StatusTrash = "trash"
|
||||
)
|
||||
|
||||
// PostType constants
|
||||
const (
|
||||
PostTypePage = "page"
|
||||
PostTypePost = "post"
|
||||
)
|
||||
|
||||
// NewPage creates a new Page entity
|
||||
func NewPage(siteID, tenantID gocql.UUID, pageID string, title, content, excerpt, url, status, postType, author string, publishedAt, modifiedAt time.Time, encryptedIP string) *Page {
|
||||
now := time.Now()
|
||||
|
||||
return &Page{
|
||||
SiteID: siteID,
|
||||
PageID: pageID,
|
||||
TenantID: tenantID,
|
||||
Title: title,
|
||||
Content: content,
|
||||
Excerpt: excerpt,
|
||||
URL: url,
|
||||
Status: status,
|
||||
PostType: postType,
|
||||
Author: author,
|
||||
PublishedAt: publishedAt,
|
||||
ModifiedAt: modifiedAt,
|
||||
IndexedAt: now,
|
||||
MeilisearchDocID: "", // Set after indexing in Meilisearch
|
||||
CreatedAt: now,
|
||||
UpdatedAt: now,
|
||||
// CWE-359: Encrypted IP address tracking for GDPR compliance
|
||||
CreatedFromIPAddress: encryptedIP,
|
||||
CreatedFromIPTimestamp: now,
|
||||
ModifiedFromIPAddress: encryptedIP,
|
||||
ModifiedFromIPTimestamp: now,
|
||||
}
|
||||
}
|
||||
|
||||
// IsPublished checks if the page is published
|
||||
func (p *Page) IsPublished() bool {
|
||||
return p.Status == StatusPublish
|
||||
}
|
||||
|
||||
// ShouldIndex checks if the page should be indexed in search
|
||||
func (p *Page) ShouldIndex() bool {
|
||||
// Only index published pages
|
||||
return p.IsPublished()
|
||||
}
|
||||
|
||||
// GetMeilisearchID returns the Meilisearch document ID
|
||||
func (p *Page) GetMeilisearchID() string {
|
||||
if p.MeilisearchDocID != "" {
|
||||
return p.MeilisearchDocID
|
||||
}
|
||||
// Use page_id as fallback
|
||||
return p.PageID
|
||||
}
|
||||
|
||||
// SetMeilisearchID sets the Meilisearch document ID
|
||||
func (p *Page) SetMeilisearchID(docID string) {
|
||||
p.MeilisearchDocID = docID
|
||||
p.UpdatedAt = time.Now()
|
||||
}
|
||||
|
||||
// MarkIndexed updates the indexed timestamp
|
||||
func (p *Page) MarkIndexed() {
|
||||
p.IndexedAt = time.Now()
|
||||
p.UpdatedAt = time.Now()
|
||||
}
|
||||
|
||||
// Update updates the page content
|
||||
func (p *Page) Update(title, content, excerpt, url, status, author string, modifiedAt time.Time) {
|
||||
p.Title = title
|
||||
p.Content = content
|
||||
p.Excerpt = excerpt
|
||||
p.URL = url
|
||||
p.Status = status
|
||||
p.Author = author
|
||||
p.ModifiedAt = modifiedAt
|
||||
p.UpdatedAt = time.Now()
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue