first commit
This commit is contained in:
51
backend/internal/domain/entities/auth.go
Normal file
51
backend/internal/domain/entities/auth.go
Normal file
@@ -0,0 +1,51 @@
|
||||
package entities
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"go.mongodb.org/mongo-driver/v2/bson"
|
||||
)
|
||||
|
||||
// AuthProvider represents a configured OAuth/OIDC provider
|
||||
type AuthProvider struct {
|
||||
ID bson.ObjectID `bson:"_id,omitempty"`
|
||||
Name string `bson:"name"`
|
||||
Type string `bson:"type"` // "oidc", "oauth2"
|
||||
ClientID string `bson:"client_id"`
|
||||
ClientSecret string `bson:"client_secret"` // Encrypted in DB
|
||||
AuthorizationURL string `bson:"authorization_url"`
|
||||
TokenURL string `bson:"token_url"`
|
||||
UserInfoURL string `bson:"userinfo_url"`
|
||||
Scopes []string `bson:"scopes"`
|
||||
IDTokenClaim string `bson:"id_token_claim,omitempty"`
|
||||
IsActive bool `bson:"is_active"`
|
||||
CreatedAt time.Time `bson:"created_at"`
|
||||
UpdatedAt time.Time `bson:"updated_at"`
|
||||
}
|
||||
|
||||
// LoginAttempt tracks login attempts for brute-force protection
|
||||
type LoginAttempt struct {
|
||||
ID bson.ObjectID `bson:"_id,omitempty"`
|
||||
Email string `bson:"email"`
|
||||
IPAddress string `bson:"ip_address"`
|
||||
Success bool `bson:"success"`
|
||||
Reason string `bson:"reason,omitempty"`
|
||||
CreatedAt time.Time `bson:"created_at"`
|
||||
ExpiresAt time.Time `bson:"expires_at"`
|
||||
}
|
||||
|
||||
// FeatureFlags controls app-wide behavior toggles.
|
||||
type FeatureFlags struct {
|
||||
RegistrationEnabled bool `bson:"registration_enabled"`
|
||||
ProviderLoginEnabled bool `bson:"provider_login_enabled"`
|
||||
PublicSharingEnabled bool `bson:"public_sharing_enabled"`
|
||||
}
|
||||
|
||||
// NewDefaultFeatureFlags returns safe defaults for a new deployment.
|
||||
func NewDefaultFeatureFlags() *FeatureFlags {
|
||||
return &FeatureFlags{
|
||||
RegistrationEnabled: true,
|
||||
ProviderLoginEnabled: true,
|
||||
PublicSharingEnabled: true,
|
||||
}
|
||||
}
|
||||
55
backend/internal/domain/entities/note.go
Normal file
55
backend/internal/domain/entities/note.go
Normal file
@@ -0,0 +1,55 @@
|
||||
package entities
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"go.mongodb.org/mongo-driver/v2/bson"
|
||||
)
|
||||
|
||||
// Note represents a note within a space
|
||||
type Note struct {
|
||||
ID bson.ObjectID `bson:"_id,omitempty"`
|
||||
SpaceID bson.ObjectID `bson:"space_id"`
|
||||
CategoryID *bson.ObjectID `bson:"category_id,omitempty"`
|
||||
Title string `bson:"title"`
|
||||
Description string `bson:"description"`
|
||||
Content string `bson:"content"`
|
||||
PasswordHash string `bson:"password_hash,omitempty"`
|
||||
Tags []string `bson:"tags"`
|
||||
IsPinned bool `bson:"is_pinned"`
|
||||
IsFavorite bool `bson:"is_favorite"`
|
||||
IsPublic bool `bson:"is_public"`
|
||||
IsPasswordProtected bool `bson:"is_password_protected"`
|
||||
CreatedBy bson.ObjectID `bson:"created_by"`
|
||||
UpdatedBy bson.ObjectID `bson:"updated_by"`
|
||||
CreatedAt time.Time `bson:"created_at"`
|
||||
UpdatedAt time.Time `bson:"updated_at"`
|
||||
ViewedAt *time.Time `bson:"viewed_at,omitempty"`
|
||||
}
|
||||
|
||||
// Category represents a folder/category within a space
|
||||
type Category struct {
|
||||
ID bson.ObjectID `bson:"_id,omitempty"`
|
||||
SpaceID bson.ObjectID `bson:"space_id"`
|
||||
Name string `bson:"name"`
|
||||
Description string `bson:"description,omitempty"`
|
||||
ParentID *bson.ObjectID `bson:"parent_id,omitempty"`
|
||||
Icon string `bson:"icon,omitempty"`
|
||||
Order int `bson:"order"`
|
||||
CreatedBy bson.ObjectID `bson:"created_by"`
|
||||
UpdatedBy bson.ObjectID `bson:"updated_by"`
|
||||
CreatedAt time.Time `bson:"created_at"`
|
||||
UpdatedAt time.Time `bson:"updated_at"`
|
||||
}
|
||||
|
||||
// NoteRevision represents a historical version of a note
|
||||
type NoteRevision struct {
|
||||
ID bson.ObjectID `bson:"_id,omitempty"`
|
||||
NoteID bson.ObjectID `bson:"note_id"`
|
||||
SpaceID bson.ObjectID `bson:"space_id"`
|
||||
Title string `bson:"title"`
|
||||
Content string `bson:"content"`
|
||||
ChangedBy bson.ObjectID `bson:"changed_by"`
|
||||
CreatedAt time.Time `bson:"created_at"`
|
||||
ChangeRef string `bson:"change_ref,omitempty"`
|
||||
}
|
||||
83
backend/internal/domain/entities/permission_group.go
Normal file
83
backend/internal/domain/entities/permission_group.go
Normal file
@@ -0,0 +1,83 @@
|
||||
package entities
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"go.mongodb.org/mongo-driver/v2/bson"
|
||||
)
|
||||
|
||||
var permissionTokenSanitizer = regexp.MustCompile(`[^a-z0-9_-]+`)
|
||||
|
||||
// PermissionGroup represents a named group of permissions.
|
||||
type PermissionGroup struct {
|
||||
ID bson.ObjectID `bson:"_id,omitempty"`
|
||||
Name string `bson:"name"`
|
||||
NameKey string `bson:"name_key"`
|
||||
Description string `bson:"description,omitempty"`
|
||||
Permissions []string `bson:"permissions"`
|
||||
IsSystem bool `bson:"is_system"`
|
||||
CreatedAt time.Time `bson:"created_at"`
|
||||
UpdatedAt time.Time `bson:"updated_at"`
|
||||
}
|
||||
|
||||
// NormalizePermission lowercases and trims a permission string.
|
||||
func NormalizePermission(permission string) string {
|
||||
return strings.ToLower(strings.TrimSpace(permission))
|
||||
}
|
||||
|
||||
// SpacePermissionToken converts a space name to a dot-safe permission token.
|
||||
func SpacePermissionToken(spaceName string) string {
|
||||
normalized := strings.ToLower(strings.TrimSpace(spaceName))
|
||||
normalized = strings.ReplaceAll(normalized, " ", "_")
|
||||
normalized = permissionTokenSanitizer.ReplaceAllString(normalized, "_")
|
||||
normalized = strings.Trim(normalized, "_")
|
||||
if normalized == "" {
|
||||
return "space"
|
||||
}
|
||||
return normalized
|
||||
}
|
||||
|
||||
// PermissionMatches reports whether a wildcard pattern matches a concrete permission.
|
||||
func PermissionMatches(pattern, permission string) bool {
|
||||
pattern = NormalizePermission(pattern)
|
||||
permission = NormalizePermission(permission)
|
||||
|
||||
if pattern == "" || permission == "" {
|
||||
return false
|
||||
}
|
||||
if pattern == "*" || pattern == permission {
|
||||
return true
|
||||
}
|
||||
if !strings.Contains(pattern, "*") {
|
||||
return false
|
||||
}
|
||||
|
||||
parts := strings.Split(pattern, "*")
|
||||
remaining := permission
|
||||
|
||||
if parts[0] != "" {
|
||||
if !strings.HasPrefix(remaining, parts[0]) {
|
||||
return false
|
||||
}
|
||||
remaining = remaining[len(parts[0]):]
|
||||
}
|
||||
|
||||
for i := 1; i < len(parts); i++ {
|
||||
part := parts[i]
|
||||
if part == "" {
|
||||
continue
|
||||
}
|
||||
idx := strings.Index(remaining, part)
|
||||
if idx < 0 {
|
||||
return false
|
||||
}
|
||||
remaining = remaining[idx+len(part):]
|
||||
}
|
||||
|
||||
if parts[len(parts)-1] != "" {
|
||||
return strings.HasSuffix(permission, parts[len(parts)-1])
|
||||
}
|
||||
return true
|
||||
}
|
||||
41
backend/internal/domain/entities/space.go
Normal file
41
backend/internal/domain/entities/space.go
Normal file
@@ -0,0 +1,41 @@
|
||||
package entities
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"go.mongodb.org/mongo-driver/v2/bson"
|
||||
)
|
||||
|
||||
// Space represents a top-level container for notes and categories
|
||||
type Space struct {
|
||||
ID bson.ObjectID `bson:"_id,omitempty"`
|
||||
Name string `bson:"name"`
|
||||
Description string `bson:"description,omitempty"`
|
||||
Icon string `bson:"icon,omitempty"`
|
||||
OwnerID bson.ObjectID `bson:"owner_id"`
|
||||
IsPublic bool `bson:"is_public"`
|
||||
CreatedAt time.Time `bson:"created_at"`
|
||||
UpdatedAt time.Time `bson:"updated_at"`
|
||||
}
|
||||
|
||||
// Membership represents a user's membership in a space
|
||||
type Membership struct {
|
||||
ID bson.ObjectID `bson:"_id,omitempty"`
|
||||
UserID bson.ObjectID `bson:"user_id"`
|
||||
SpaceID bson.ObjectID `bson:"space_id"`
|
||||
JoinedAt time.Time `bson:"joined_at"`
|
||||
InvitedBy bson.ObjectID `bson:"invited_by,omitempty"`
|
||||
InvitedAt *time.Time `bson:"invited_at,omitempty"`
|
||||
}
|
||||
|
||||
// SpaceInvitation represents an invitation to join a space
|
||||
type SpaceInvitation struct {
|
||||
ID bson.ObjectID `bson:"_id,omitempty"`
|
||||
SpaceID bson.ObjectID `bson:"space_id"`
|
||||
Email string `bson:"email"`
|
||||
Token string `bson:"token"`
|
||||
CreatedBy bson.ObjectID `bson:"created_by"`
|
||||
CreatedAt time.Time `bson:"created_at"`
|
||||
ExpiresAt time.Time `bson:"expires_at"`
|
||||
AcceptedAt *time.Time `bson:"accepted_at,omitempty"`
|
||||
}
|
||||
51
backend/internal/domain/entities/user.go
Normal file
51
backend/internal/domain/entities/user.go
Normal file
@@ -0,0 +1,51 @@
|
||||
package entities
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"go.mongodb.org/mongo-driver/v2/bson"
|
||||
)
|
||||
|
||||
// User represents a system user
|
||||
type User struct {
|
||||
ID bson.ObjectID `bson:"_id,omitempty"`
|
||||
Email string `bson:"email"`
|
||||
Username string `bson:"username"`
|
||||
PasswordHash string `bson:"password_hash"`
|
||||
FirstName string `bson:"first_name"`
|
||||
LastName string `bson:"last_name"`
|
||||
Avatar string `bson:"avatar,omitempty"`
|
||||
GroupIDs []bson.ObjectID `bson:"group_ids,omitempty"`
|
||||
Permissions []string `bson:"permissions,omitempty"`
|
||||
IsActive bool `bson:"is_active"`
|
||||
EmailVerified bool `bson:"email_verified"`
|
||||
CreatedAt time.Time `bson:"created_at"`
|
||||
UpdatedAt time.Time `bson:"updated_at"`
|
||||
LastLoginAt *time.Time `bson:"last_login_at,omitempty"`
|
||||
}
|
||||
|
||||
// UserProviderLink links external OAuth/OIDC providers to a user
|
||||
type UserProviderLink struct {
|
||||
ID bson.ObjectID `bson:"_id,omitempty"`
|
||||
UserID bson.ObjectID `bson:"user_id"`
|
||||
ProviderID bson.ObjectID `bson:"provider_id"`
|
||||
ProviderUserID string `bson:"provider_user_id"`
|
||||
Email string `bson:"email"`
|
||||
ProfileData map[string]any `bson:"profile_data,omitempty"`
|
||||
AccessToken string `bson:"access_token"` // Consider encrypting in production
|
||||
RefreshToken string `bson:"refresh_token,omitempty"`
|
||||
AccessTokenExp *time.Time `bson:"access_token_exp,omitempty"`
|
||||
LinkedAt time.Time `bson:"linked_at"`
|
||||
LastUsedAt *time.Time `bson:"last_used_at,omitempty"`
|
||||
}
|
||||
|
||||
// AccountRecovery represents account recovery tokens
|
||||
type AccountRecovery struct {
|
||||
ID bson.ObjectID `bson:"_id,omitempty"`
|
||||
UserID bson.ObjectID `bson:"user_id"`
|
||||
Token string `bson:"token"`
|
||||
Type string `bson:"type"` // "password_reset", "email_verification"
|
||||
ExpiresAt time.Time `bson:"expires_at"`
|
||||
UsedAt *time.Time `bson:"used_at,omitempty"`
|
||||
CreatedAt time.Time `bson:"created_at"`
|
||||
}
|
||||
40
backend/internal/domain/repositories/additional.go
Normal file
40
backend/internal/domain/repositories/additional.go
Normal file
@@ -0,0 +1,40 @@
|
||||
package repositories
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/noteapp/backend/internal/domain/entities"
|
||||
"go.mongodb.org/mongo-driver/v2/bson"
|
||||
)
|
||||
|
||||
// AccountRecoveryRepository defines account recovery operations
|
||||
type AccountRecoveryRepository interface {
|
||||
CreateRecovery(ctx context.Context, recovery *entities.AccountRecovery) error
|
||||
GetRecoveryByToken(ctx context.Context, token string) (*entities.AccountRecovery, error)
|
||||
MarkRecoveryUsed(ctx context.Context, id bson.ObjectID) error
|
||||
}
|
||||
|
||||
// FeatureFlagRepository defines app feature-flag operations.
|
||||
type FeatureFlagRepository interface {
|
||||
GetFeatureFlags(ctx context.Context) (*entities.FeatureFlags, error)
|
||||
UpdateFeatureFlags(ctx context.Context, flags *entities.FeatureFlags) error
|
||||
}
|
||||
|
||||
// Additional repository extensions
|
||||
type (
|
||||
// SpaceRepository extensions
|
||||
SpaceRepositoryExt interface {
|
||||
SpaceRepository
|
||||
}
|
||||
|
||||
// MembershipRepository extensions
|
||||
MembershipRepositoryExt interface {
|
||||
MembershipRepository
|
||||
GetUserMemberships(ctx context.Context, userID bson.ObjectID) ([]*entities.Membership, error)
|
||||
}
|
||||
|
||||
// NoteRepository extensions
|
||||
NoteRepositoryExt interface {
|
||||
NoteRepository
|
||||
}
|
||||
)
|
||||
215
backend/internal/domain/repositories/interfaces.go
Normal file
215
backend/internal/domain/repositories/interfaces.go
Normal file
@@ -0,0 +1,215 @@
|
||||
package repositories
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/noteapp/backend/internal/domain/entities"
|
||||
"go.mongodb.org/mongo-driver/v2/bson"
|
||||
)
|
||||
|
||||
// UserRepository defines user operations
|
||||
type UserRepository interface {
|
||||
// CreateUser creates a new user
|
||||
CreateUser(ctx context.Context, user *entities.User) error
|
||||
|
||||
// GetUserByID retrieves a user by ID
|
||||
GetUserByID(ctx context.Context, id bson.ObjectID) (*entities.User, error)
|
||||
|
||||
// GetUserByEmail retrieves a user by email
|
||||
GetUserByEmail(ctx context.Context, email string) (*entities.User, error)
|
||||
|
||||
// GetUserByUsername retrieves a user by username
|
||||
GetUserByUsername(ctx context.Context, username string) (*entities.User, error)
|
||||
|
||||
// UpdateUser updates a user
|
||||
UpdateUser(ctx context.Context, user *entities.User) error
|
||||
|
||||
// DeleteUser deletes a user
|
||||
DeleteUser(ctx context.Context, id bson.ObjectID) error
|
||||
|
||||
// ListAllUsers retrieves all users (admin use)
|
||||
ListAllUsers(ctx context.Context) ([]*entities.User, error)
|
||||
}
|
||||
|
||||
// GroupRepository defines permission group operations
|
||||
type GroupRepository interface {
|
||||
// CreateGroup creates a new permission group
|
||||
CreateGroup(ctx context.Context, group *entities.PermissionGroup) error
|
||||
|
||||
// GetGroupByID retrieves a group by ID
|
||||
GetGroupByID(ctx context.Context, id bson.ObjectID) (*entities.PermissionGroup, error)
|
||||
|
||||
// GetGroupByName retrieves a group by name
|
||||
GetGroupByName(ctx context.Context, name string) (*entities.PermissionGroup, error)
|
||||
|
||||
// GetGroupsByIDs retrieves groups by IDs
|
||||
GetGroupsByIDs(ctx context.Context, ids []bson.ObjectID) ([]*entities.PermissionGroup, error)
|
||||
|
||||
// ListGroups retrieves all groups
|
||||
ListGroups(ctx context.Context) ([]*entities.PermissionGroup, error)
|
||||
|
||||
// UpdateGroup updates an existing group
|
||||
UpdateGroup(ctx context.Context, group *entities.PermissionGroup) error
|
||||
|
||||
// DeleteGroup deletes a group
|
||||
DeleteGroup(ctx context.Context, id bson.ObjectID) error
|
||||
}
|
||||
|
||||
// SpaceRepository defines space operations
|
||||
type SpaceRepository interface {
|
||||
// CreateSpace creates a new space
|
||||
CreateSpace(ctx context.Context, space *entities.Space) error
|
||||
|
||||
// GetSpaceByID retrieves a space by ID
|
||||
GetSpaceByID(ctx context.Context, id bson.ObjectID) (*entities.Space, error)
|
||||
|
||||
// GetSpacesByUserID retrieves all spaces for a user
|
||||
GetSpacesByUserID(ctx context.Context, userID bson.ObjectID) ([]*entities.Space, error)
|
||||
|
||||
// GetAllSpaces retrieves all spaces (admin use)
|
||||
GetAllSpaces(ctx context.Context) ([]*entities.Space, error)
|
||||
|
||||
// GetPublicSpaces retrieves all spaces marked as public
|
||||
GetPublicSpaces(ctx context.Context) ([]*entities.Space, error)
|
||||
|
||||
// UpdateSpace updates a space
|
||||
UpdateSpace(ctx context.Context, space *entities.Space) error
|
||||
|
||||
// DeleteSpace deletes a space
|
||||
DeleteSpace(ctx context.Context, id bson.ObjectID) error
|
||||
}
|
||||
|
||||
// MembershipRepository defines membership operations
|
||||
type MembershipRepository interface {
|
||||
// CreateMembership creates a new membership
|
||||
CreateMembership(ctx context.Context, membership *entities.Membership) error
|
||||
|
||||
// GetMembershipByID retrieves a membership by ID
|
||||
GetMembershipByID(ctx context.Context, id bson.ObjectID) (*entities.Membership, error)
|
||||
|
||||
// GetUserMembership retrieves a membership for a user in a space
|
||||
GetUserMembership(ctx context.Context, userID, spaceID bson.ObjectID) (*entities.Membership, error)
|
||||
|
||||
// GetSpaceMembers retrieves all members in a space
|
||||
GetSpaceMembers(ctx context.Context, spaceID bson.ObjectID) ([]*entities.Membership, error)
|
||||
|
||||
// GetUserMemberships retrieves all memberships for a user
|
||||
GetUserMemberships(ctx context.Context, userID bson.ObjectID) ([]*entities.Membership, error)
|
||||
|
||||
// UpdateMembership updates a membership
|
||||
UpdateMembership(ctx context.Context, membership *entities.Membership) error
|
||||
|
||||
// DeleteMembership deletes a membership
|
||||
DeleteMembership(ctx context.Context, id bson.ObjectID) error
|
||||
|
||||
// DeleteMembershipsBySpaceID deletes all memberships for a space
|
||||
DeleteMembershipsBySpaceID(ctx context.Context, spaceID bson.ObjectID) error
|
||||
}
|
||||
|
||||
// NoteRepository defines note operations
|
||||
type NoteRepository interface {
|
||||
// CreateNote creates a new note
|
||||
CreateNote(ctx context.Context, note *entities.Note) error
|
||||
|
||||
// GetNoteByID retrieves a note by ID
|
||||
GetNoteByID(ctx context.Context, id bson.ObjectID) (*entities.Note, error)
|
||||
|
||||
// GetNotesBySpaceID retrieves all notes in a space
|
||||
GetNotesBySpaceID(ctx context.Context, spaceID bson.ObjectID, skip, limit int) ([]*entities.Note, error)
|
||||
|
||||
// GetPublicNotesBySpaceID retrieves public notes in a space
|
||||
GetPublicNotesBySpaceID(ctx context.Context, spaceID bson.ObjectID, skip, limit int) ([]*entities.Note, error)
|
||||
|
||||
// GetNotesByCategory retrieves notes in a category
|
||||
GetNotesByCategory(ctx context.Context, spaceID, categoryID bson.ObjectID) ([]*entities.Note, error)
|
||||
|
||||
// SearchNotes performs full-text search on notes
|
||||
SearchNotes(ctx context.Context, spaceID bson.ObjectID, query string) ([]*entities.Note, error)
|
||||
|
||||
// UpdateNote updates a note
|
||||
UpdateNote(ctx context.Context, note *entities.Note) error
|
||||
|
||||
// DeleteNote deletes a note
|
||||
DeleteNote(ctx context.Context, id bson.ObjectID) error
|
||||
|
||||
// DeleteNotesBySpaceID deletes all notes in a space
|
||||
DeleteNotesBySpaceID(ctx context.Context, spaceID bson.ObjectID) error
|
||||
}
|
||||
|
||||
// CategoryRepository defines category operations
|
||||
type CategoryRepository interface {
|
||||
// CreateCategory creates a new category
|
||||
CreateCategory(ctx context.Context, category *entities.Category) error
|
||||
|
||||
// GetCategoryByID retrieves a category by ID
|
||||
GetCategoryByID(ctx context.Context, id bson.ObjectID) (*entities.Category, error)
|
||||
|
||||
// GetCategoriesBySpaceID retrieves all categories in a space
|
||||
GetCategoriesBySpaceID(ctx context.Context, spaceID bson.ObjectID) ([]*entities.Category, error)
|
||||
|
||||
// GetRootCategories retrieves root level categories in a space
|
||||
GetRootCategories(ctx context.Context, spaceID bson.ObjectID) ([]*entities.Category, error)
|
||||
|
||||
// GetSubcategories retrieves subcategories of a category
|
||||
GetSubcategories(ctx context.Context, parentID bson.ObjectID) ([]*entities.Category, error)
|
||||
|
||||
// UpdateCategory updates a category
|
||||
UpdateCategory(ctx context.Context, category *entities.Category) error
|
||||
|
||||
// DeleteCategory deletes a category
|
||||
DeleteCategory(ctx context.Context, id bson.ObjectID) error
|
||||
|
||||
// DeleteCategoriesBySpaceID deletes all categories in a space
|
||||
DeleteCategoriesBySpaceID(ctx context.Context, spaceID bson.ObjectID) error
|
||||
}
|
||||
|
||||
// AuthProviderRepository defines auth provider operations
|
||||
type AuthProviderRepository interface {
|
||||
// CreateProvider creates a new auth provider
|
||||
CreateProvider(ctx context.Context, provider *entities.AuthProvider) error
|
||||
|
||||
// GetProviderByID retrieves a provider by ID
|
||||
GetProviderByID(ctx context.Context, id bson.ObjectID) (*entities.AuthProvider, error)
|
||||
|
||||
// GetAllProviders retrieves all active providers
|
||||
GetAllProviders(ctx context.Context) ([]*entities.AuthProvider, error)
|
||||
|
||||
// UpdateProvider updates a provider
|
||||
UpdateProvider(ctx context.Context, provider *entities.AuthProvider) error
|
||||
|
||||
// DeleteProvider deletes a provider
|
||||
DeleteProvider(ctx context.Context, id bson.ObjectID) error
|
||||
}
|
||||
|
||||
// UserProviderLinkRepository defines user provider link operations
|
||||
type UserProviderLinkRepository interface {
|
||||
// CreateLink creates a new user provider link
|
||||
CreateLink(ctx context.Context, link *entities.UserProviderLink) error
|
||||
|
||||
// GetLink retrieves a user provider link
|
||||
GetLink(ctx context.Context, userID, providerID bson.ObjectID) (*entities.UserProviderLink, error)
|
||||
|
||||
// GetLinkByProviderUserID retrieves a link by provider user ID
|
||||
GetLinkByProviderUserID(ctx context.Context, providerID bson.ObjectID, providerUserID string) (*entities.UserProviderLink, error)
|
||||
|
||||
// GetUserLinks retrieves all provider links for a user
|
||||
GetUserLinks(ctx context.Context, userID bson.ObjectID) ([]*entities.UserProviderLink, error)
|
||||
|
||||
// UpdateLink updates a provider link
|
||||
UpdateLink(ctx context.Context, link *entities.UserProviderLink) error
|
||||
|
||||
// DeleteLink deletes a provider link
|
||||
DeleteLink(ctx context.Context, id bson.ObjectID) error
|
||||
}
|
||||
|
||||
// NoteRevisionRepository defines note revision operations
|
||||
type NoteRevisionRepository interface {
|
||||
// CreateRevision creates a new note revision
|
||||
CreateRevision(ctx context.Context, revision *entities.NoteRevision) error
|
||||
|
||||
// GetRevisionsByNoteID retrieves all revisions for a note
|
||||
GetRevisionsByNoteID(ctx context.Context, noteID bson.ObjectID) ([]*entities.NoteRevision, error)
|
||||
|
||||
// GetRevisionByID retrieves a specific revision
|
||||
GetRevisionByID(ctx context.Context, id bson.ObjectID) (*entities.NoteRevision, error)
|
||||
}
|
||||
Reference in New Issue
Block a user