feat: add SymposiumSeeder and MessengerSeeder bridge interfaces

Defines cross-plugin seeder interfaces in the SDK so template plugins
can seed Symposium/Messenger content via PluginBridge without importing
their database packages directly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Alex Dunmow 2026-05-03 00:16:46 +08:00
parent 601718a309
commit b2c968af41

105
plugin/seeder.go Normal file
View File

@ -0,0 +1,105 @@
package plugin
import (
"context"
"github.com/jackc/pgx/v5"
)
// SymposiumSeeder provides Symposium data-seeding and lookup operations for
// cross-plugin use via PluginBridge. Template plugins retrieve this interface
// instead of importing the Symposium database package directly.
//
// All Seed* methods are idempotent: existing rows are returned, not duplicated.
type SymposiumSeeder interface {
// Wiki
SeedWikiCategory(ctx context.Context, tx pgx.Tx, name, slug, description string, sortOrder int32) (string, error)
SeedWikiArticle(ctx context.Context, tx pgx.Tx, title, slug, categoryID, excerpt string, contentJSON []byte) error
// Courses
SeedCourse(ctx context.Context, tx pgx.Tx, p SeedCourseParams) (string, error)
SeedCourseSection(ctx context.Context, tx pgx.Tx, courseID, title string, position int32) (string, error)
SeedLesson(ctx context.Context, tx pgx.Tx, courseID, sectionID string, p SeedLessonParams) (string, error)
// Quizzes
SeedQuiz(ctx context.Context, tx pgx.Tx, title string, passThreshold int32) (string, error)
SeedQuizQuestion(ctx context.Context, tx pgx.Tx, quizID string, p SeedQuizQuestionParams) (string, error)
// Community
SeedCommunityCategory(ctx context.Context, tx pgx.Tx, name, slug, description, icon string, position, minTierLevel int32) (string, error)
// Course categories & tags
SeedCourseCategory(ctx context.Context, tx pgx.Tx, name, slug string, description *string, position int32) error
SeedCourseTag(ctx context.Context, tx pgx.Tx, name, slug string, position *int32) error
// Lookups — return the entity ID or an error if not found.
GetCourseBySlug(ctx context.Context, tx pgx.Tx, slug string) (string, error)
GetCommunityCategoryBySlug(ctx context.Context, tx pgx.Tx, slug string) (string, error)
// Runtime queries
GetUserCourseProgress(ctx context.Context, pool Pool, userID string) ([]CourseProgressItem, error)
}
// SeedCourseParams holds the parameters for seeding a course.
type SeedCourseParams struct {
Title string
Slug string
Description string
CertificateEnabled bool
MinTierLevel int32
DifficultyLevel string
EstimatedDurationMinutes int32
}
// SeedLessonParams holds the parameters for seeding a lesson.
type SeedLessonParams struct {
Title string
Slug string
LessonType string
ContentJSON []byte
QuizID string
Position int32
IsFreePreview bool
CompletionMode string
}
// SeedQuizQuestionParams holds the parameters for seeding a quiz question.
type SeedQuizQuestionParams struct {
QuestionType string
QuestionText string
Options []map[string]any
CorrectAnswer string
Explanation string
Position int32
Rubric string
ScenarioText string
}
// CourseProgressItem is a lightweight view of a user's progress in one course.
type CourseProgressItem struct {
CourseTitle string
CourseSlug string
NextLesson string
DoneCount int
TotalLessons int
}
// MessengerSeeder provides Messenger data-seeding operations for cross-plugin
// use via PluginBridge. Template plugins retrieve this interface instead of
// importing the Messenger database package directly.
type MessengerSeeder interface {
CountMessagesForPair(ctx context.Context, tx pgx.Tx, participantPairID string) (int64, error)
InsertMessage(ctx context.Context, tx pgx.Tx, p InsertMessageParams) error
}
// InsertMessageParams holds the parameters for inserting a messenger message.
type InsertMessageParams struct {
SenderType string
SenderID string
SenderDisplayName string
RecipientType string
RecipientID string
RecipientDisplayName string
BodyMarkdown string
ParticipantPairID string
}