db

package
v0.0.0-...-b59dd2f Latest Latest
Warning

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

Go to latest
Published: Jun 24, 2026 License: Apache-2.0 Imports: 12 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrSelfRelation      = errors.New("self-referential relation")
	ErrDuplicateRelation = errors.New("duplicate relation")
	ErrCycleDetected     = errors.New("cycle detected")
)

Sentinel errors for relation operations.

View Source
var ErrConflict = errors.New("conflict")

ErrConflict is returned when an operation violates a uniqueness or state constraint.

View Source
var ErrLabelColorConflict = errors.New("label color conflict")

ErrLabelColorConflict is returned when --color specifies a different color than an existing label already has.

View Source
var ErrNotAttached = errors.New("label not attached")

ErrNotAttached is returned when a label is not attached to the specified issue.

View Source
var ErrNotFound = errors.New("not found")

ErrNotFound is returned when a requested resource does not exist.

View Source
var ErrValidation = errors.New("validation")

ErrValidation is returned when an input fails a validation precondition that the DB layer enforces (e.g., negative revision number). CLI surfaces map this to output.ErrValidation. See TDD docket-doc-cli §6.4.

Functions

func AddLabelToIssue

func AddLabelToIssue(db *sql.DB, issueID int, labelName, color string, author string) error

AddLabelToIssue attaches a label to an issue within a transaction. The label is created if it does not already exist (with the given color). Activity is recorded and the issue's updated_at timestamp is touched.

func AddLabelsToIssue

func AddLabelsToIssue(db *sql.DB, issueID int, labelNames []string, color string, author string) error

AddLabelsToIssue attaches multiple labels to an issue atomically within a single transaction. Labels are created if they do not already exist (with the given color). Activity is recorded for each newly attached label and the issue's updated_at timestamp is touched once.

func AttachFiles

func AttachFiles(db *sql.DB, issueID int, filePaths []string, changedBy string) error

AttachFiles inserts rows into issue_files for each file path. Duplicate attachments are silently ignored (INSERT OR IGNORE). Activity is recorded for each batch of newly attached files.

func CascadeDeleteIssue

func CascadeDeleteIssue(db *sql.DB, id int) error

CascadeDeleteIssue deletes an issue and all its descendants recursively in a single transaction. The recursive CTE finds all descendant issues; ON DELETE CASCADE constraints on comments, issue_labels, issue_relations, and activity_log handle cleanup of related rows automatically.

func ClearAllData

func ClearAllData(db *sql.DB) error

ClearAllData deletes all data from every persistent table within a single transaction. The schema and meta table are preserved.

Tables are deleted in FK-correct order — children before parents. FK CASCADE would handle dependents implicitly, but the explicit ordering keeps behaviour identical to the pre-v4 function and makes the contract auditable from the function body.

Doc tables and the pre-existing proposals/votes/proposal_issues tables are included; prior to v4 the latter three were silently omitted, which broke `--replace` import on any DB containing proposals (TDD §5.4 S4 / R7).

func ClearAllDataTx

func ClearAllDataTx(tx *sql.Tx) error

func CommitProposal

func CommitProposal(db *sql.DB, id int, outcome string, escalationReason string) error

CommitProposal transitions an approved proposal to committed status with a final outcome. If escalationReason is non-empty, it is stored on the proposal.

func CountByPriority

func CountByPriority(db *sql.DB) (map[string]int, error)

CountByPriority returns a map of priority -> count for all issues.

func CountByStatus

func CountByStatus(db *sql.DB) (map[string]int, error)

CountByStatus returns a map of status -> count for all issues.

func CountIssues

func CountIssues(db *sql.DB) (int, error)

CountIssues returns the total number of issues in the database.

func CountRootIssues

func CountRootIssues(db *sql.DB) (int, error)

CountRootIssues returns the number of issues with no parent.

func CreateComment

func CreateComment(db *sql.DB, comment *model.Comment) (int, error)

CreateComment inserts a new comment for an issue, records activity, and returns its ID. The insert and activity log are wrapped in a single transaction so they succeed or fail together.

func CreateDoc

func CreateDoc(db *sql.DB, doc *model.Doc) (int, error)

CreateDoc inserts a new doc and appends revision #1 with change_kind="create" in a single transaction. Returns the new doc ID. The supplied doc must have Type, Status, Title, Body, and Author set; CreatedAt/UpdatedAt are stamped by this function.

func CreateDocComment

func CreateDocComment(db *sql.DB, c *model.DocComment) (int, error)

CreateDocComment inserts a comment on a doc and returns its ID. The doc existence check and insert run in a single transaction. Returns ErrNotFound if the doc does not exist.

func CreateIssue

func CreateIssue(db *sql.DB, issue *model.Issue, labels []string, files []string) (int, error)

CreateIssue inserts a new issue and returns its ID. Labels are created (find-or-create) and linked to the issue within the same transaction. Files are attached to the issue if provided.

func CreateProposal

func CreateProposal(db *sql.DB, p *model.Proposal) (int, error)

CreateProposal inserts a new proposal and returns its ID.

func CreateRelation

func CreateRelation(db *sql.DB, rel *model.Relation) (int, error)

CreateRelation inserts a new relation between two issues within a single transaction. It validates that both issues exist, rejects self-referential and duplicate relations, runs cycle detection for blocks/depends_on types, and records activity on both issues.

func DeleteDoc

func DeleteDoc(db *sql.DB, id int, cascade bool) error

DeleteDoc removes the doc with the given ID. When cascade is true, FK cascades drop doc_revisions, doc_comments, doc_issue_links, proposal_docs. When cascade is false, the call returns ErrConflict if any links (issue or proposal) exist for the doc — comments and revisions are part of the doc's own history and never block deletion. Returns ErrNotFound if no doc with that ID exists.

func DeleteIssue

func DeleteIssue(db *sql.DB, id int) error

DeleteIssue removes an issue by ID. Foreign key cascades handle cleanup of related rows (comments, labels, activity, relations).

func DeleteLabel

func DeleteLabel(db *sql.DB, labelID int, name, author string) ([]int, error)

DeleteLabel removes a label by ID. CASCADE constraints handle cleanup of issue_labels rows. Activity is recorded for each affected issue using the provided name. Returns the list of issue IDs that were attached to the label.

func DeleteRelation

func DeleteRelation(db *sql.DB, sourceID, targetID int, relType string) error

DeleteRelation removes a relation matching the given source, target, and type. Activity is recorded on both issues within a single transaction.

func DetachFiles

func DetachFiles(db *sql.DB, issueID int, filePaths []string, changedBy string) error

DetachFiles deletes rows from issue_files matching the issue ID and file paths. Activity is recorded for removed files.

func GetActivity

func GetActivity(db *sql.DB, issueID int, limit int) ([]model.Activity, error)

GetActivity retrieves activity log entries for an issue, ordered by most recent first.

func GetAllDirectionalRelations

func GetAllDirectionalRelations(db *sql.DB) ([]model.Relation, error)

GetAllDirectionalRelations returns all relations where the relation type is "blocks" or "depends_on", ordered by creation time ascending.

func GetAllRelations

func GetAllRelations(db *sql.DB) ([]model.Relation, error)

GetAllRelations returns every relation in the database, ordered by creation time ascending.

func GetBatchSubIssueProgress

func GetBatchSubIssueProgress(conn *sql.DB, parentIDs []int) (map[int][2]int, error)

GetBatchSubIssueProgress returns (done, total) counts for descendants of each given parent ID in a single query, avoiding N+1 overhead.

func GetComment

func GetComment(db *sql.DB, id int) (*model.Comment, error)

GetComment retrieves a comment by ID.

func GetDoc

func GetDoc(db *sql.DB, id int) (*model.Doc, error)

GetDoc returns the doc with the given ID, or ErrNotFound.

func GetDocComment

func GetDocComment(db *sql.DB, id int) (*model.DocComment, error)

GetDocComment returns a single doc comment by ID, or ErrNotFound.

func GetDocIssues

func GetDocIssues(db *sql.DB, docID int) ([]int, error)

GetDocIssues returns issue IDs linked to a doc, ordered by issue_id ASC.

func GetDocProposals

func GetDocProposals(db *sql.DB, docID int) ([]int, error)

GetDocProposals returns proposal IDs linked to a doc, ordered by proposal_id ASC.

func GetDocRevision

func GetDocRevision(db *sql.DB, docID, rev int) (*model.DocRevision, error)

GetDocRevision returns revision rev of the doc with the given ID. Per TDD §3.3 / §6.3 (Q1): rev < 0 → ErrValidation; rev > MAX → ErrNotFound. rev == 0 is treated as "the current revision" (the most-recent one).

func GetIssue

func GetIssue(db *sql.DB, id int) (*model.Issue, error)

GetIssue retrieves an issue by ID.

func GetIssueDocs

func GetIssueDocs(db *sql.DB, issueID int) ([]int, error)

GetIssueDocs returns doc IDs linked to an issue, ordered by doc_id ASC.

func GetIssueFiles

func GetIssueFiles(db *sql.DB, issueID int) ([]string, error)

GetIssueFiles returns the file paths attached to an issue, sorted alphabetically.

func GetIssueLabelObjects

func GetIssueLabelObjects(db *sql.DB, issueID int) ([]*model.Label, error)

GetIssueLabelObjects returns the full Label objects attached to an issue, sorted alphabetically by name.

func GetIssueLabels

func GetIssueLabels(db *sql.DB, issueID int) ([]string, error)

GetIssueLabels returns the label names attached to an issue, sorted alphabetically.

func GetIssueProposals

func GetIssueProposals(db *sql.DB, issueID int) ([]model.Proposal, error)

GetIssueProposals returns the proposals linked to an issue, ordered by proposal id ascending. It is the reverse edge of GetProposalIssues.

func GetIssueRelations

func GetIssueRelations(db *sql.DB, issueID int) ([]model.Relation, error)

GetIssueRelations returns all relations where the given issue is either the source or the target, ordered by creation time ascending.

func GetIssuesByIDs

func GetIssuesByIDs(db *sql.DB, ids []int) (map[int]*model.Issue, error)

GetIssuesByIDs retrieves multiple issues by their IDs in a single query. The returned map is keyed by issue ID. IDs that don't exist are silently skipped (no error for missing rows). Labels are hydrated on all returned issues.

func GetLabelByName

func GetLabelByName(db *sql.DB, name string) (*model.LabelWithCount, error)

GetLabelByName retrieves a label by its unique name, including the count of issues currently attached to it. Returns ErrNotFound if no label with that name exists.

func GetProposal

func GetProposal(db *sql.DB, id int) (*model.Proposal, error)

GetProposal returns a proposal by ID, or ErrNotFound if it does not exist.

func GetProposalDocs

func GetProposalDocs(db *sql.DB, proposalID int) ([]int, error)

GetProposalDocs returns doc IDs linked to a proposal, ordered by doc_id ASC.

func GetProposalIssues

func GetProposalIssues(db *sql.DB, proposalID int) ([]int, error)

GetProposalIssues returns the issue IDs linked to a proposal.

func GetProposalVotes

func GetProposalVotes(db *sql.DB, proposalID int) ([]*model.Vote, error)

GetProposalVotes returns all votes for a proposal, ordered by creation time.

func GetSubIssueProgress

func GetSubIssueProgress(db *sql.DB, parentID int) (int, int, error)

GetSubIssueProgress returns (done, total) counts for all descendants of an issue.

func GetSubIssueTree

func GetSubIssueTree(db *sql.DB, parentID int) ([]*model.Issue, error)

GetSubIssueTree returns the full recursive tree of all descendants under an issue.

func GetSubIssues

func GetSubIssues(db *sql.DB, parentID int) ([]*model.Issue, error)

GetSubIssues returns all direct children of an issue.

func HydrateDocs

func HydrateDocs(db *sql.DB, issues []*model.Issue) error

func HydrateFiles

func HydrateFiles(db *sql.DB, issues []*model.Issue) error

HydrateFiles bulk-loads files for a set of issues, populating each issue's Files field. This avoids N+1 queries in list views and the planner.

func HydrateLabels

func HydrateLabels(db *sql.DB, issues []*model.Issue) error

HydrateLabels bulk-loads labels for a set of issues, populating each issue's Labels field. This avoids N+1 queries when displaying lists.

func HydrateLinkedIssues

func HydrateLinkedIssues(db *sql.DB, docIDs []int) (map[int][]model.IssueRef, error)

func Initialize

func Initialize(db *sql.DB) error

Initialize creates all tables if they don't exist and sets the schema version.

func InsertActivityWithID

func InsertActivityWithID(tx *sql.Tx, a *model.Activity) (bool, error)

InsertActivityWithID inserts an activity_log row with a caller-supplied ID, skipping if the ID already exists. Must be called within an existing transaction. Returns true if inserted. Mirrors InsertIssueWithID.

func InsertCommentWithID

func InsertCommentWithID(tx *sql.Tx, comment *model.Comment) (bool, error)

InsertCommentWithID inserts a comment with a specific ID (not auto-increment), skipping if the ID already exists. Returns true if the row was inserted. Must be called within an existing transaction.

func InsertDocCommentWithID

func InsertDocCommentWithID(tx *sql.Tx, c *model.DocComment) (bool, error)

InsertDocCommentWithID inserts a doc_comments row with a caller-supplied ID, skipping if the ID already exists. Returns true if inserted. Must be called within an existing transaction. Mirrors InsertCommentWithID.

func InsertDocIssueLink(tx *sql.Tx, docID, issueID int, createdAt string) (bool, error)

InsertDocIssueLink inserts a doc_issue_links row, skipping on PK conflict. Used by export/import round-trip. Must be called within a transaction. Returns true if inserted.

func InsertDocRevisionWithID

func InsertDocRevisionWithID(tx *sql.Tx, r *model.DocRevision) (bool, error)

InsertDocRevisionWithID inserts a doc_revisions row with a caller-supplied ID, skipping if the ID already exists. Must be called within a transaction. Returns true if inserted. Mirrors InsertIssueWithID.

func InsertDocWithID

func InsertDocWithID(tx *sql.Tx, doc *model.Doc) (bool, error)

InsertDocWithID inserts a doc row with a caller-supplied ID, skipping if the ID already exists. Mirrors InsertIssueWithID (TDD §5.3 round-trip helpers). Must be called within an existing transaction. Returns true if inserted.

func InsertIssueFileMapping

func InsertIssueFileMapping(tx *sql.Tx, issueID int, filePath string) (bool, error)

InsertIssueFileMapping inserts a single file mapping using INSERT OR IGNORE. Returns true if inserted, false if already existed. Must be called within an existing transaction.

func InsertIssueLabelMapping

func InsertIssueLabelMapping(tx *sql.Tx, issueID, labelID int) (bool, error)

InsertIssueLabelMapping inserts an issue_labels row linking an issue to a label, skipping if the mapping already exists. Returns true if the row was inserted. Must be called within an existing transaction.

func InsertIssueWithID

func InsertIssueWithID(tx *sql.Tx, issue *model.Issue) (bool, error)

InsertIssueWithID inserts an issue with a specific ID (not auto-increment), skipping if the ID already exists. Returns true if the row was inserted. Must be called within an existing transaction.

func InsertLabelWithID

func InsertLabelWithID(tx *sql.Tx, label *model.Label) (bool, error)

InsertLabelWithID inserts a label with a specific ID (not auto-increment), skipping if the ID already exists. Returns true if the row was inserted. Must be called within an existing transaction.

func InsertProposalDocLink(tx *sql.Tx, proposalID, docID int, createdAt string) (bool, error)

InsertProposalDocLink inserts a proposal_docs row, skipping on PK conflict. Must be called within a transaction. Returns true if inserted.

func InsertProposalIssueLink(tx *sql.Tx, proposalID, issueID int) (bool, error)

InsertProposalIssueLink inserts a proposal_issues row, skipping on PK conflict. Must be called within a transaction. Returns true if inserted.

func InsertProposalWithID

func InsertProposalWithID(tx *sql.Tx, p *model.Proposal) (bool, error)

InsertProposalWithID inserts a proposal row with a caller-supplied ID, skipping if the ID already exists. Must be called within an existing transaction. Returns true if inserted. Mirrors InsertIssueWithID; domain_tags and files_changed are JSON-encoded identically to CreateProposal.

func InsertRelationWithID

func InsertRelationWithID(tx *sql.Tx, rel *model.Relation) (bool, error)

InsertRelationWithID inserts a relation with a specific ID (not auto-increment), skipping if the ID already exists. Returns true if the row was inserted. Must be called within an existing transaction.

func InsertVoteWithID

func InsertVoteWithID(tx *sql.Tx, v *model.Vote) (bool, error)

InsertVoteWithID inserts a vote row with a caller-supplied ID, skipping if the ID already exists. Must be called within an existing transaction. Returns true if inserted. findings_json is JSON-encoded (NULL when absent) identically to CastVote.

func IsDescendant

func IsDescendant(db *sql.DB, issueID, potentialDescendantID int) (bool, error)

IsDescendant returns true if potentialDescendantID is a descendant of issueID. This is used to detect cycles when reparenting an issue.

func IssueExists

func IssueExists(db *sql.DB, issueID int) (bool, error)

IssueExists returns true if an issue with the given ID exists.

func LinkDocIssue

func LinkDocIssue(db *sql.DB, docID, issueID int) error

LinkDocIssue links a doc to an issue. Returns ErrNotFound if either side is missing; ErrConflict if the link already exists.

func LinkProposalDoc

func LinkProposalDoc(db *sql.DB, proposalID, docID int) error

LinkProposalDoc links a proposal (vote) to a doc. Returns ErrNotFound if either side is missing; ErrConflict if the link already exists.

func LinkProposalIssue

func LinkProposalIssue(db *sql.DB, proposalID, issueID int) error

LinkProposalIssue links a proposal to an issue. Returns ErrNotFound if the proposal or issue does not exist. Returns ErrConflict if the link already exists.

func ListAllActivity

func ListAllActivity(db *sql.DB) ([]*model.Activity, error)

ListAllActivity returns every activity_log row ordered by id ASC, for a full export.

func ListAllComments

func ListAllComments(db *sql.DB) ([]*model.Comment, error)

ListAllComments returns every comment in the database across all issues, ordered by created_at ascending.

func ListAllDocComments

func ListAllDocComments(db *sql.DB) ([]*model.DocComment, error)

ListAllDocComments returns every doc_comments row ordered by id ASC, for a full export.

func ListAllDocIssueLinks(db *sql.DB) ([]model.DocIssueLink, error)

ListAllDocIssueLinks returns every doc_issue_links row ordered by (doc_id, issue_id), for a full export.

func ListAllDocRevisions

func ListAllDocRevisions(db *sql.DB) ([]*model.DocRevision, error)

ListAllDocRevisions returns every doc_revisions row ordered by id ASC, for a full export.

func ListAllDocs

func ListAllDocs(db *sql.DB) ([]*model.Doc, error)

ListAllDocs returns every doc row ordered by id ASC, for a full export.

func ListAllIssueFileMappings

func ListAllIssueFileMappings(db *sql.DB) ([]model.IssueFileMapping, error)

ListAllIssueFileMappings returns all rows from issue_files as IssueFileMapping structs. This is needed by the export command.

func ListAllIssueLabelMappings

func ListAllIssueLabelMappings(db *sql.DB) ([]model.IssueLabelMapping, error)

ListAllIssueLabelMappings returns all (issue_id, label_id) pairs from the issue_labels table.

func ListAllIssues

func ListAllIssues(db *sql.DB) ([]*model.Issue, error)

ListAllIssues returns every issue in the database, including done issues, with no filters, sorting, or pagination. Labels are hydrated on all results.

func ListAllLabels

func ListAllLabels(db *sql.DB) ([]*model.LabelWithCount, error)

ListAllLabels returns every label along with the count of issues using it, sorted alphabetically by name.

func ListAllLabelsRaw

func ListAllLabelsRaw(db *sql.DB) ([]*model.Label, error)

ListAllLabelsRaw returns every label as a model.Label object (without issue counts), sorted alphabetically by name.

func ListAllProposalDocs

func ListAllProposalDocs(db *sql.DB) ([]model.ProposalDocLink, error)

ListAllProposalDocs returns every proposal_docs row ordered by (proposal_id, doc_id), for a full export.

func ListAllProposalIssues

func ListAllProposalIssues(db *sql.DB) ([]model.ProposalIssueLink, error)

ListAllProposalIssues returns every proposal_issues row ordered by (proposal_id, issue_id), for a full export.

func ListAllProposals

func ListAllProposals(db *sql.DB) ([]*model.Proposal, error)

ListAllProposals returns every proposal row ordered by id ASC, for a full export.

func ListAllVotes

func ListAllVotes(db *sql.DB) ([]*model.Vote, error)

ListAllVotes returns every vote row ordered by id ASC, for a full export.

func ListComments

func ListComments(db *sql.DB, issueID int) ([]*model.Comment, error)

ListComments retrieves all comments for an issue, ordered by creation time ascending.

func ListDocComments

func ListDocComments(db *sql.DB, docID int) ([]*model.DocComment, error)

ListDocComments returns all comments for a doc ordered by created_at ASC. Returns an empty slice (not nil) when the doc has no comments; returns ErrNotFound when the doc itself is missing.

func ListDocRevisions

func ListDocRevisions(db *sql.DB, docID int) ([]*model.DocRevision, error)

ListDocRevisions returns every revision row for the doc, ordered by revision_number ascending. Returns ErrNotFound when the doc itself is missing.

func ListDocs

func ListDocs(db *sql.DB, opts DocListOptions) ([]*model.Doc, int, error)

ListDocs returns docs matching opts, ordered and paginated. Returns the matching rows and the total count before limit/offset.

func ListIssues

func ListIssues(db *sql.DB, opts ListOptions) ([]*model.Issue, int, error)

ListIssues retrieves issues matching the given filters. It returns the matching issues, the total count of matching rows (ignoring Limit/Offset), and an error.

func ListProposals

func ListProposals(db *sql.DB, status string, criticality string, domainTag string, limit int) ([]*model.Proposal, int, error)

ListProposals returns proposals with optional filters. It returns the matching proposals and the total count (before limit).

func Migrate

func Migrate(db *sql.DB) error

Migrate checks the current schema version and applies any pending migrations sequentially. It is a no-op when already at the latest version.

func Open

func Open(dbPath string) (*sql.DB, error)

Open opens or creates the SQLite database at the given path. It sets pragmas for WAL mode, foreign key enforcement, and busy timeout.

func OrphanSubIssues

func OrphanSubIssues(db *sql.DB, parentID int, author string) error

OrphanSubIssues sets parent_id to NULL for all direct children of the given issue. Activity is recorded for each affected child within a transaction.

func RecordActivity

func RecordActivity(ex execer, issueID int, field, oldVal, newVal, changedBy string) error

RecordActivity logs a field change on an issue.

func RemoveLabelFromIssue

func RemoveLabelFromIssue(db *sql.DB, issueID int, labelName string, author string) error

RemoveLabelFromIssue detaches a label from an issue. Returns an error if the label is not found or is not attached to the issue. Activity is recorded and the issue's updated_at timestamp is touched.

func RemoveLabelsFromIssue

func RemoveLabelsFromIssue(db *sql.DB, issueID int, labelNames []string, author string) error

RemoveLabelsFromIssue detaches multiple labels from an issue atomically within a single transaction. Returns an error if any label is not found or not attached — no labels are removed on failure. Activity is recorded for each removed label and the issue's updated_at timestamp is touched once.

func SchemaVersion

func SchemaVersion(db *sql.DB) (int, error)

SchemaVersion returns the current schema version from the meta table.

func SetIssueFiles

func SetIssueFiles(db *sql.DB, issueID int, filePaths []string, changedBy string) error

SetIssueFiles replaces all files for an issue (delete existing, insert new). Activity is recorded showing the change from old files to new files.

func UnlinkDocIssue

func UnlinkDocIssue(db *sql.DB, docID, issueID int) error

UnlinkDocIssue removes a doc↔issue link. Returns ErrNotFound if no such link exists.

func UnlinkProposalDoc

func UnlinkProposalDoc(db *sql.DB, proposalID, docID int) error

UnlinkProposalDoc removes a proposal↔doc link. Returns ErrNotFound if no such link exists.

func UnlinkProposalIssue

func UnlinkProposalIssue(db *sql.DB, proposalID, issueID int) error

UnlinkProposalIssue removes a link between a proposal and an issue. Returns ErrNotFound if the link does not exist.

func UpdateDoc

func UpdateDoc(db *sql.DB, id int, upd DocUpdate) (int, error)

UpdateDoc applies the changes in upd to the doc with the given ID and appends one revision row capturing the combined change_kind. Returns the new revision number (0 if no revision appended because nothing changed).

Per TDD §5.4 C8, every persisted field change appends one revision; the change_kind is comma-joined ("+" separator) for multi-field edits. Body equality uses strings.TrimRight(s, "\n") so trailing-newline-only edits are no-ops and do NOT append a revision (C6).

Returns ErrNotFound if id does not exist.

func UpdateIssue

func UpdateIssue(db *sql.DB, id int, updates map[string]interface{}, changedBy string) error

UpdateIssue updates an existing issue. Only keys present in the updates map are modified. The updated_at timestamp is always set to the current time. Activity is recorded for each changed field within the same transaction.

Field names are validated against validUpdateFields, but callers are responsible for validating field values (e.g. ensuring status/priority/kind are valid enums) before calling this function.

Types

type CastVoteResult

type CastVoteResult struct {
	Vote           *model.Vote
	ProposalStatus model.ProposalStatus
	VotesCast      int
	VotesRequired  int
	QuorumReached  bool
	WeightedScore  *float64
}

CastVoteResult holds the outcome of a CastVote operation, including whether quorum was reached and the proposal's updated status.

func CastVote

func CastVote(db *sql.DB, v *model.Vote) (*CastVoteResult, error)

CastVote inserts a vote and auto-finalizes the proposal when quorum is reached. Returns ErrNotFound if the proposal does not exist. Returns ErrConflict if the voter already voted or the proposal is already finalized.

type CycleError

type CycleError struct {
	Path []int
}

CycleError wraps ErrCycleDetected and carries the path of IDs forming the cycle.

func (*CycleError) Error

func (e *CycleError) Error() string

func (*CycleError) Unwrap

func (e *CycleError) Unwrap() error

type DocListOptions

type DocListOptions struct {
	Types    []string
	Statuses []string
	Author   string
	Sort     string
	SortDir  string
	Limit    int
	Offset   int
}

DocListOptions holds filtering, sorting, and pagination options for ListDocs and ListDocsWithCounts. Mirrors ListOptions/issues but with the doc-table columns.

type DocSummary

type DocSummary struct {
	Doc             *model.Doc
	RevisionsCount  int
	CurrentRevision int
}

DocSummary is a row from ListDocsWithCounts: a Doc plus the JOIN-derived revision count and current revision number. Returned shape per TDD §6.3.

func ListDocsWithCounts

func ListDocsWithCounts(db *sql.DB, opts DocListOptions) ([]*DocSummary, int, error)

ListDocsWithCounts returns DocSummary rows including JOIN-derived revisions_count and current_revision in a single query (TDD §5.4 S1 — no N+1). Returns total count (before limit) as the second value.

type DocUpdate

type DocUpdate struct {
	Title  *string
	Body   *string
	Status *string
	Type   *string
	Author string
}

DocUpdate is the set of fields UpdateDoc may change. Nil pointers mean "leave unchanged"; non-nil with the current value is detected as a no-op (body equality additionally applies trailing-newline trimming — C6).

type ListOptions

type ListOptions struct {
	Statuses    []string // filter by status (multiple = OR)
	Priorities  []string // filter by priority (multiple = OR)
	Labels      []string // filter by label name (multiple = AND)
	Types       []string // filter by kind (multiple = OR)
	Assignee    string   // filter by assignee
	ParentID    *int     // filter by parent issue ID
	RootsOnly   bool     // only issues with no parent
	IncludeDone bool     // include done status (default: exclude)
	Sort        string   // field name
	SortDir     string   // "asc" or "desc"
	Limit       int      // max results
	Offset      int      // for pagination
}

ListOptions holds filtering, sorting, and pagination options for ListIssues.

Jump to

Keyboard shortcuts

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