From c6db6dc4b7d4379863e37651016cc4e6a3642c46 Mon Sep 17 00:00:00 2001 From: adlerhurst <27845747+adlerhurst@users.noreply.github.com> Date: Thu, 8 May 2025 19:01:55 +0200 Subject: [PATCH] add documentation --- backend/main.go | 1 - backend/v3/doc.go | 11 ++++++++++- backend/v3/domain/command.go | 9 +++++++++ backend/v3/domain/create_user.go | 5 +++++ backend/v3/domain/crypto.go | 4 ++++ backend/v3/domain/domain.go | 2 ++ backend/v3/domain/domain_test.go | 1 + backend/v3/domain/email_verification.go | 5 +++++ backend/v3/domain/instance.go | 5 +++++ backend/v3/domain/invoke.go | 14 ++++++++++++++ backend/v3/domain/org.go | 17 +++++++++-------- backend/v3/domain/org_add.go | 4 ++++ backend/v3/domain/set_email.go | 4 ++++ backend/v3/domain/user.go | 13 +++++++++++++ backend/v3/storage/cache/doc.go | 2 ++ backend/v3/storage/database/change.go | 2 ++ backend/v3/storage/database/column.go | 3 +++ backend/v3/storage/database/condition.go | 9 +++++++++ backend/v3/storage/database/config.go | 1 + backend/v3/storage/database/database.go | 19 ++++++++----------- .../storage/database/dialect/postgres/doc.go | 2 ++ backend/v3/storage/database/operators.go | 3 +++ backend/v3/storage/database/repository/doc.go | 5 +++++ backend/v3/storage/database/tx.go | 2 ++ backend/v3/telemetry/logging/logger.go | 1 + backend/v3/telemetry/metric/doc.go | 2 ++ backend/v3/telemetry/tracing/tracer.go | 1 + 27 files changed, 126 insertions(+), 21 deletions(-) create mode 100644 backend/v3/storage/cache/doc.go create mode 100644 backend/v3/storage/database/dialect/postgres/doc.go create mode 100644 backend/v3/storage/database/repository/doc.go create mode 100644 backend/v3/telemetry/metric/doc.go diff --git a/backend/main.go b/backend/main.go index 3f1b3f1747..fa01b77310 100644 --- a/backend/main.go +++ b/backend/main.go @@ -1,6 +1,5 @@ /* Copyright © 2025 NAME HERE - */ package main diff --git a/backend/v3/doc.go b/backend/v3/doc.go index 7032207dcd..8798c1ce94 100644 --- a/backend/v3/doc.go +++ b/backend/v3/doc.go @@ -1,12 +1,21 @@ // the test used the manly relies on the following patterns: +// - api: +// - some example stubs for the grpc api, it maps the calls and responses to the domain objects +// // - domain: // - hexagonal architecture, it defines its dependencies as interfaces and the dependencies must use the objects defined by this package // - command pattern which implements the changes -// - the invoker decorates the commands by checking for events and tracing +// - the invoker decorates the commands by checking for events, tracing, logging, potentially caching, etc. // - the database connections are manged in this package // - the database connections are passed to the repositories // // - storage: // - repository pattern, the repositories are defined as interfaces and the implementations are in the storage package // - the repositories are used by the domain package to access the database +// - the eventstore to store events. At the beginning it writes to the same events table as the /internal package, afterwards it writes to a different table +// +// - telemetry: +// - logging for standard output +// - tracing for distributed tracing +// - metrics for monitoring package v3 diff --git a/backend/v3/domain/command.go b/backend/v3/domain/command.go index 6db0e12b5d..18bb185132 100644 --- a/backend/v3/domain/command.go +++ b/backend/v3/domain/command.go @@ -7,15 +7,22 @@ import ( "github.com/zitadel/zitadel/backend/v3/storage/database" ) +// Commander is the all it needs to implement the command pattern. +// It is the interface all manipulations need to implement. +// If possible it should also be used for queries. We will find out if this is possible in the future. type Commander interface { Execute(ctx context.Context, opts *CommandOpts) (err error) fmt.Stringer } +// Invoker is part of the command pattern. +// It is the interface that is used to execute commands. type Invoker interface { Invoke(ctx context.Context, command Commander, opts *CommandOpts) error } +// CommandOpts are passed to each command +// the provide common fields used by commands like the database client. type CommandOpts struct { DB database.QueryExecutor Invoker Invoker @@ -95,6 +102,8 @@ func DefaultOpts(invoker Invoker) *CommandOpts { } } +// commandBatch is a batch of commands. +// It uses the [Invoker] provided by the opts to execute each command. type commandBatch struct { Commands []Commander } diff --git a/backend/v3/domain/create_user.go b/backend/v3/domain/create_user.go index dbf9b1b45b..fd5edb4d22 100644 --- a/backend/v3/domain/create_user.go +++ b/backend/v3/domain/create_user.go @@ -6,6 +6,10 @@ import ( "github.com/zitadel/zitadel/backend/v3/storage/eventstore" ) +// CreateUserCommand adds a new user including the email verification for humans. +// In the future it might make sense to separate the command into two commands: +// - CreateHumanCommand: creates a new human user +// - CreateMachineCommand: creates a new machine user type CreateUserCommand struct { user *User email *SetEmailCommand @@ -16,6 +20,7 @@ var ( _ eventer = (*CreateUserCommand)(nil) ) +// opts heavily reduces the complexity for email verification because each type of verification is a simple option which implements the [Commander] interface. func NewCreateHumanCommand(username string, opts ...CreateHumanOpt) *CreateUserCommand { cmd := &CreateUserCommand{ user: &User{ diff --git a/backend/v3/domain/crypto.go b/backend/v3/domain/crypto.go index 8df9bbd021..ad22faa25e 100644 --- a/backend/v3/domain/crypto.go +++ b/backend/v3/domain/crypto.go @@ -11,6 +11,10 @@ type generateCodeCommand struct { value *crypto.CryptoValue } +// I didn't update this repository to the solution proposed please view one of the following interfaces for correct usage: +// - [UserRepository] +// - [InstanceRepository] +// - [OrgRepository] type CryptoRepository interface { GetEncryptionConfig(ctx context.Context) (*crypto.GeneratorConfig, error) } diff --git a/backend/v3/domain/domain.go b/backend/v3/domain/domain.go index a9ed30fbc8..64c9477d8e 100644 --- a/backend/v3/domain/domain.go +++ b/backend/v3/domain/domain.go @@ -11,6 +11,8 @@ import ( "github.com/zitadel/zitadel/internal/crypto" ) +// The variables could also be moved to a struct. +// I just started with the singleton pattern and kept it like this. var ( pool database.Pool userCodeAlgorithm crypto.EncryptionAlgorithm diff --git a/backend/v3/domain/domain_test.go b/backend/v3/domain/domain_test.go index 28c51f1322..dbb7084512 100644 --- a/backend/v3/domain/domain_test.go +++ b/backend/v3/domain/domain_test.go @@ -19,6 +19,7 @@ import ( "github.com/zitadel/zitadel/backend/v3/telemetry/tracing" ) +// These tests give an overview of how to use the domain package. func TestExample(t *testing.T) { ctx := context.Background() diff --git a/backend/v3/domain/email_verification.go b/backend/v3/domain/email_verification.go index bde9a9041f..54f36aa80e 100644 --- a/backend/v3/domain/email_verification.go +++ b/backend/v3/domain/email_verification.go @@ -5,6 +5,7 @@ import ( "time" ) +// EmailVerifiedCommand verifies an email address for a user. type EmailVerifiedCommand struct { UserID string `json:"userId"` Email *Email `json:"email"` @@ -42,6 +43,8 @@ func (cmd *EmailVerifiedCommand) applyOnSetEmail(setEmailCmd *SetEmailCommand) { setEmailCmd.verification = cmd } +// SendCodeCommand sends a verification code to the user's email address. +// If the URLTemplate is not set it will use the default of the organization / instance. type SendCodeCommand struct { UserID string `json:"userId"` Email string `json:"email"` @@ -113,6 +116,8 @@ func (cmd *SendCodeCommand) applyOnSetEmail(setEmailCmd *SetEmailCommand) { setEmailCmd.verification = cmd } +// ReturnCodeCommand creates the code and returns it to the caller. +// The caller gets the code by calling the Code field after the command got executed. type ReturnCodeCommand struct { UserID string `json:"userId"` Email string `json:"email"` diff --git a/backend/v3/domain/instance.go b/backend/v3/domain/instance.go index 7b965dc2f1..1ff12c9d0a 100644 --- a/backend/v3/domain/instance.go +++ b/backend/v3/domain/instance.go @@ -33,6 +33,7 @@ func (i *Instance) Keys(index instanceCacheIndex) (key []string) { var _ cache.Entry[instanceCacheIndex, string] = (*Instance)(nil) +// instanceColumns define all the columns of the instance table. type instanceColumns interface { // IDColumn returns the column for the id field. IDColumn() database.Column @@ -46,6 +47,7 @@ type instanceColumns interface { DeletedAtColumn() database.Column } +// instanceConditions define all the conditions for the instance table. type instanceConditions interface { // IDCondition returns an equal filter on the id field. IDCondition(instanceID string) database.Condition @@ -53,16 +55,19 @@ type instanceConditions interface { NameCondition(op database.TextOperation, name string) database.Condition } +// instanceChanges define all the changes for the instance table. type instanceChanges interface { // SetName sets the name column. SetName(name string) database.Change } +// InstanceRepository is the interface for the instance repository. type InstanceRepository interface { instanceColumns instanceConditions instanceChanges + // Member returns the member repository which is a sub repository of the instance repository. Member() MemberRepository Get(ctx context.Context, opts ...database.QueryOption) (*Instance, error) diff --git a/backend/v3/domain/invoke.go b/backend/v3/domain/invoke.go index 3cb63af161..2bc286361f 100644 --- a/backend/v3/domain/invoke.go +++ b/backend/v3/domain/invoke.go @@ -7,6 +7,10 @@ import ( "github.com/zitadel/zitadel/backend/v3/storage/eventstore" ) +// Invoke provides a way to execute commands within the domain package. +// It uses a chain of responsibility pattern to handle the command execution. +// The default chain includes logging, tracing, and event publishing. +// If you want to invoke multiple commands in a single transaction, you can use the [commandBatch]. func Invoke(ctx context.Context, cmd Commander) error { invoker := newEventStoreInvoker(newLoggingInvoker(newTraceInvoker(nil))) opts := &CommandOpts{ @@ -16,6 +20,8 @@ func Invoke(ctx context.Context, cmd Commander) error { return invoker.Invoke(ctx, cmd, opts) } +// eventStoreInvoker checks if the command implements the [eventer] interface. +// If it does, it collects the events and publishes them to the event store. type eventStoreInvoker struct { collector *eventCollector } @@ -38,6 +44,7 @@ func (i *eventStoreInvoker) Invoke(ctx context.Context, command Commander, opts return nil } +// eventCollector collects events from all commands. The [eventStoreInvoker] pushes the collected events after all commands are executed. type eventCollector struct { next Invoker events []*eventstore.Event @@ -64,6 +71,7 @@ func (i *eventCollector) Invoke(ctx context.Context, command Commander, opts *Co return command.Execute(ctx, opts) } +// traceInvoker decorates each command with tracing. type traceInvoker struct { next Invoker } @@ -87,6 +95,8 @@ func (i *traceInvoker) Invoke(ctx context.Context, command Commander, opts *Comm return command.Execute(ctx, opts) } +// loggingInvoker decorates each command with logging. +// It is an example implementation and logs the command name at the beginning and success or failure after the command got executed. type loggingInvoker struct { next Invoker } @@ -123,6 +133,10 @@ func (i *noopInvoker) Invoke(ctx context.Context, command Commander, opts *Comma return command.Execute(ctx, opts) } +// cacheInvoker could be used in the future to do the caching. +// My goal would be to have two interfaces: +// - cacheSetter: which caches an object +// - cacheGetter: which gets an object from the cache, this should also skip the command execution type cacheInvoker struct { next Invoker } diff --git a/backend/v3/domain/org.go b/backend/v3/domain/org.go index 413dfc30ee..0f80e58a73 100644 --- a/backend/v3/domain/org.go +++ b/backend/v3/domain/org.go @@ -15,6 +15,7 @@ const ( OrgStateInactive ) +// Org is used by all other packages to represent an organization. type Org struct { ID string `json:"id"` Name string `json:"name"` @@ -42,6 +43,7 @@ func (o *Org) Keys(index orgCacheIndex) (key []string) { var _ cache.Entry[orgCacheIndex, string] = (*Org)(nil) +// orgColumns define all the columns of the org table. type orgColumns interface { // InstanceIDColumn returns the column for the instance id field. InstanceIDColumn() database.Column @@ -59,6 +61,7 @@ type orgColumns interface { DeletedAtColumn() database.Column } +// orgConditions define all the conditions for the org table. type orgConditions interface { // InstanceIDCondition returns an equal filter on the instance id field. InstanceIDCondition(instanceID string) database.Condition @@ -70,6 +73,7 @@ type orgConditions interface { StateCondition(op database.NumberOperation, state OrgState) database.Condition } +// orgChanges define all the changes for the org table. type orgChanges interface { // SetName sets the name column. SetName(name string) database.Change @@ -77,12 +81,14 @@ type orgChanges interface { SetState(state OrgState) database.Change } +// OrgRepository is the interface for the org repository. +// It is used to interact with the org table in the database. type OrgRepository interface { orgColumns orgConditions orgChanges - // Member returns the admin repository. + // Member returns the member repository. Member() MemberRepository // Domain returns the domain repository. Domain() DomainRepository @@ -99,19 +105,14 @@ type OrgRepository interface { Update(ctx context.Context, condition database.Condition, changes ...database.Change) error } -type OrgOperation interface { - MemberRepository - DomainRepository - Update(ctx context.Context, org *Org) error - Delete(ctx context.Context) error -} - +// MemberRepository is a sub repository of the org repository and maybe the instance repository. type MemberRepository interface { AddMember(ctx context.Context, orgID, userID string, roles []string) error SetMemberRoles(ctx context.Context, orgID, userID string, roles []string) error RemoveMember(ctx context.Context, orgID, userID string) error } +// DomainRepository is a sub repository of the org repository and maybe the instance repository. type DomainRepository interface { AddDomain(ctx context.Context, domain string) error SetDomainVerified(ctx context.Context, domain string) error diff --git a/backend/v3/domain/org_add.go b/backend/v3/domain/org_add.go index a94ce53589..23175ac349 100644 --- a/backend/v3/domain/org_add.go +++ b/backend/v3/domain/org_add.go @@ -6,6 +6,8 @@ import ( "github.com/zitadel/zitadel/backend/v3/storage/eventstore" ) +// AddOrgCommand adds a new organization. +// I'm unsure if we should add the Admins here or if this should be a separate command. type AddOrgCommand struct { ID string `json:"id"` Name string `json:"name"` @@ -86,6 +88,8 @@ func (cmd *AddOrgCommand) ensureID() (err error) { return err } +// AddMemberCommand adds a new member to an organization. +// I'm not sure if we should make it more generic to also use it for instances. type AddMemberCommand struct { orgID string UserID string `json:"userId"` diff --git a/backend/v3/domain/set_email.go b/backend/v3/domain/set_email.go index dd0abb49d6..649438809b 100644 --- a/backend/v3/domain/set_email.go +++ b/backend/v3/domain/set_email.go @@ -6,6 +6,10 @@ import ( "github.com/zitadel/zitadel/backend/v3/storage/eventstore" ) +// SetEmailCommand sets the email address of a user. +// If allows verification as a sub command. +// The verification command is executed after the email address is set. +// The verification command is executed in the same transaction as the email address update. type SetEmailCommand struct { UserID string `json:"userId"` Email string `json:"email"` diff --git a/backend/v3/domain/user.go b/backend/v3/domain/user.go index 99d86d2467..fae0d75b6e 100644 --- a/backend/v3/domain/user.go +++ b/backend/v3/domain/user.go @@ -7,6 +7,7 @@ import ( "github.com/zitadel/zitadel/backend/v3/storage/database" ) +// userColumns define all the columns of the user table. type userColumns interface { // InstanceIDColumn returns the column for the instance id field. InstanceIDColumn() database.Column @@ -24,6 +25,7 @@ type userColumns interface { DeletedAtColumn() database.Column } +// userConditions define all the conditions for the user table. type userConditions interface { // InstanceIDCondition returns an equal filter on the instance id field. InstanceIDCondition(instanceID string) database.Condition @@ -43,11 +45,13 @@ type userConditions interface { DeletedAtCondition(op database.NumberOperation, deletedAt time.Time) database.Condition } +// userChanges define all the changes for the user table. type userChanges interface { // SetUsername sets the username column. SetUsername(username string) database.Change } +// UserRepository is the interface for the user repository. type UserRepository interface { userColumns userConditions @@ -66,6 +70,7 @@ type UserRepository interface { Machine() MachineRepository } +// humanColumns define all the columns of the human table which inherits the user table. type humanColumns interface { userColumns // FirstNameColumn returns the column for the first name field. @@ -82,6 +87,7 @@ type humanColumns interface { PhoneVerifiedAtColumn() database.Column } +// humanConditions define all the conditions for the human table which inherits the user table. type humanConditions interface { userConditions // FirstNameCondition returns a filter on the first name field. @@ -103,6 +109,7 @@ type humanConditions interface { PhoneVerifiedAtCondition(op database.NumberOperation, phoneVerifiedAt time.Time) database.Condition } +// humanChanges define all the changes for the human table which inherits the user table. type humanChanges interface { userChanges // SetFirstName sets the first name field of the human. @@ -129,6 +136,7 @@ type humanChanges interface { SetPhoneVerifiedAt(at time.Time) database.Change } +// HumanRepository is the interface for the human repository it inherits the user repository. type HumanRepository interface { humanColumns humanConditions @@ -140,24 +148,28 @@ type HumanRepository interface { Update(ctx context.Context, condition database.Condition, changes ...database.Change) error } +// machineColumns define all the columns of the machine table which inherits the user table. type machineColumns interface { userColumns // DescriptionColumn returns the column for the description field. DescriptionColumn() database.Column } +// machineConditions define all the conditions for the machine table which inherits the user table. type machineConditions interface { userConditions // DescriptionCondition returns a filter on the description field. DescriptionCondition(op database.TextOperation, description string) database.Condition } +// machineChanges define all the changes for the machine table which inherits the user table. type machineChanges interface { userChanges // SetDescription sets the description field of the machine. SetDescription(description string) database.Change } +// MachineRepository is the interface for the machine repository it inherits the user repository. type MachineRepository interface { // Update updates machine users based on the given condition and changes. Update(ctx context.Context, condition database.Condition, changes ...database.Change) error @@ -167,6 +179,7 @@ type MachineRepository interface { machineChanges } +// UserTraits is implemented by [Human] and [Machine]. type UserTraits interface { Type() UserType } diff --git a/backend/v3/storage/cache/doc.go b/backend/v3/storage/cache/doc.go new file mode 100644 index 0000000000..a6e357989b --- /dev/null +++ b/backend/v3/storage/cache/doc.go @@ -0,0 +1,2 @@ +// this package is copy pasted from the internal/cache package +package cache diff --git a/backend/v3/storage/database/change.go b/backend/v3/storage/database/change.go index b5e6dfbba3..a8e949324f 100644 --- a/backend/v3/storage/database/change.go +++ b/backend/v3/storage/database/change.go @@ -1,5 +1,7 @@ package database +// Change represents a change to a column in a database table. +// Its written in the SET clause of an UPDATE statement. type Change interface { Write(builder *StatementBuilder) } diff --git a/backend/v3/storage/database/column.go b/backend/v3/storage/database/column.go index 801926730d..7e2629dbdd 100644 --- a/backend/v3/storage/database/column.go +++ b/backend/v3/storage/database/column.go @@ -12,6 +12,7 @@ func (m Columns) Write(builder *StatementBuilder) { } } +// Column represents a column in a database table. type Column interface { Write(builder *StatementBuilder) } @@ -31,6 +32,8 @@ func (c column) Write(builder *StatementBuilder) { var _ Column = (*column)(nil) +// ignoreCaseColumn represents two database columns, one for the +// original value and one for the lower case value. type ignoreCaseColumn interface { Column WriteIgnoreCase(builder *StatementBuilder) diff --git a/backend/v3/storage/database/condition.go b/backend/v3/storage/database/condition.go index a58952660f..e47b520dd1 100644 --- a/backend/v3/storage/database/condition.go +++ b/backend/v3/storage/database/condition.go @@ -1,5 +1,7 @@ package database +// Condition represents a SQL condition. +// Its written after the WHERE keyword in a SQL statement. type Condition interface { Write(builder *StatementBuilder) } @@ -22,6 +24,7 @@ func (a *and) Write(builder *StatementBuilder) { } } +// And combines multiple conditions with AND. func And(conditions ...Condition) *and { return &and{conditions: conditions} } @@ -46,6 +49,7 @@ func (o *or) Write(builder *StatementBuilder) { } } +// Or combines multiple conditions with OR. func Or(conditions ...Condition) *or { return &or{conditions: conditions} } @@ -62,6 +66,7 @@ func (i *isNull) Write(builder *StatementBuilder) { builder.WriteString(" IS NULL") } +// IsNull creates a condition that checks if a column is NULL. func IsNull(column Column) *isNull { return &isNull{column: column} } @@ -78,6 +83,7 @@ func (i *isNotNull) Write(builder *StatementBuilder) { builder.WriteString(" IS NOT NULL") } +// IsNotNull creates a condition that checks if a column is NOT NULL. func IsNotNull(column Column) *isNotNull { return &isNotNull{column: column.(Column)} } @@ -86,18 +92,21 @@ var _ Condition = (*isNotNull)(nil) type valueCondition func(builder *StatementBuilder) +// NewTextCondition creates a condition that compares a text column with a value. func NewTextCondition[V Text](col Column, op TextOperation, value V) Condition { return valueCondition(func(builder *StatementBuilder) { writeTextOperation(builder, col, op, value) }) } +// NewDateCondition creates a condition that compares a numeric column with a value. func NewNumberCondition[V Number](col Column, op NumberOperation, value V) Condition { return valueCondition(func(builder *StatementBuilder) { writeNumberOperation(builder, col, op, value) }) } +// NewDateCondition creates a condition that compares a boolean column with a value. func NewBooleanCondition[V Boolean](col Column, value V) Condition { return valueCondition(func(builder *StatementBuilder) { writeBooleanOperation(builder, col, value) diff --git a/backend/v3/storage/database/config.go b/backend/v3/storage/database/config.go index d9aa99b869..8b20eb24d7 100644 --- a/backend/v3/storage/database/config.go +++ b/backend/v3/storage/database/config.go @@ -4,6 +4,7 @@ import ( "context" ) +// Connector abstracts the database driver. type Connector interface { Connect(ctx context.Context) (Pool, error) } diff --git a/backend/v3/storage/database/database.go b/backend/v3/storage/database/database.go index 33d297adf0..709dda0be0 100644 --- a/backend/v3/storage/database/database.go +++ b/backend/v3/storage/database/database.go @@ -4,15 +4,7 @@ import ( "context" ) -var ( - db *database -) - -type database struct { - connector Connector - pool Pool -} - +// Pool is a connection pool. e.g. pgxpool type Pool interface { Beginner QueryExecutor @@ -21,6 +13,7 @@ type Pool interface { Close(ctx context.Context) error } +// Client is a single database connection which can be released back to the pool. type Client interface { Beginner QueryExecutor @@ -28,33 +21,37 @@ type Client interface { Release(ctx context.Context) error } +// Querier is a database client that can execute queries and return rows. type Querier interface { Query(ctx context.Context, stmt string, args ...any) (Rows, error) QueryRow(ctx context.Context, stmt string, args ...any) Row } +// Executor is a database client that can execute statements. type Executor interface { Exec(ctx context.Context, stmt string, args ...any) error } +// QueryExecutor is a database client that can execute queries and statements. type QueryExecutor interface { Querier Executor } +// Scanner scans a single row of data into the destination. type Scanner interface { Scan(dest ...any) error } +// Row is an abstraction of sql.Row. type Row interface { Scanner } +// Rows is an abstraction of sql.Rows. type Rows interface { Row Next() bool Close() error Err() error } - -type Query[T any] func(querier Querier) (result T, err error) diff --git a/backend/v3/storage/database/dialect/postgres/doc.go b/backend/v3/storage/database/dialect/postgres/doc.go new file mode 100644 index 0000000000..8b21e4766d --- /dev/null +++ b/backend/v3/storage/database/dialect/postgres/doc.go @@ -0,0 +1,2 @@ +// pgxpool v5 implementation of the interfaces defined in the database package. +package postgres diff --git a/backend/v3/storage/database/operators.go b/backend/v3/storage/database/operators.go index 8c9021e1f5..a2949220e9 100644 --- a/backend/v3/storage/database/operators.go +++ b/backend/v3/storage/database/operators.go @@ -18,6 +18,7 @@ type Text interface { ~string | ~[]byte } +// TextOperation are operations that can be performed on text values. type TextOperation uint8 const ( @@ -89,6 +90,7 @@ type Number interface { constraints.Integer | constraints.Float | constraints.Complex | time.Time | time.Duration } +// NumberOperation are operations that can be performed on number values. type NumberOperation uint8 const ( @@ -125,6 +127,7 @@ type Boolean interface { ~bool } +// BooleanOperation are operations that can be performed on boolean values. type BooleanOperation uint8 const ( diff --git a/backend/v3/storage/database/repository/doc.go b/backend/v3/storage/database/repository/doc.go new file mode 100644 index 0000000000..bd01ea6dec --- /dev/null +++ b/backend/v3/storage/database/repository/doc.go @@ -0,0 +1,5 @@ +// Package implements the repositories defined in the domain package. +// The repositories are used by the domain package to access the database. +// the inheritance.sql file is me over-engineering table inheritance. +// I would create a user table which is inherited by human_user and machine_user and the same for objects like idps. +package repository diff --git a/backend/v3/storage/database/tx.go b/backend/v3/storage/database/tx.go index 02c945dc77..a8f7adab58 100644 --- a/backend/v3/storage/database/tx.go +++ b/backend/v3/storage/database/tx.go @@ -2,6 +2,7 @@ package database import "context" +// Transaction is an SQL transaction. type Transaction interface { Commit(ctx context.Context) error Rollback(ctx context.Context) error @@ -12,6 +13,7 @@ type Transaction interface { QueryExecutor } +// Beginner can start a new transaction. type Beginner interface { Begin(ctx context.Context, opts *TransactionOptions) (Transaction, error) } diff --git a/backend/v3/telemetry/logging/logger.go b/backend/v3/telemetry/logging/logger.go index d8f36e30ec..a7d724daff 100644 --- a/backend/v3/telemetry/logging/logger.go +++ b/backend/v3/telemetry/logging/logger.go @@ -2,6 +2,7 @@ package logging import "log/slog" +// Logger abstracts [slog.Logger] not sure if thats needed type Logger struct { *slog.Logger } diff --git a/backend/v3/telemetry/metric/doc.go b/backend/v3/telemetry/metric/doc.go new file mode 100644 index 0000000000..e4a8b3bd63 --- /dev/null +++ b/backend/v3/telemetry/metric/doc.go @@ -0,0 +1,2 @@ +// implementation of otel metrics +package metric diff --git a/backend/v3/telemetry/tracing/tracer.go b/backend/v3/telemetry/tracing/tracer.go index 4536092947..025a0c1116 100644 --- a/backend/v3/telemetry/tracing/tracer.go +++ b/backend/v3/telemetry/tracing/tracer.go @@ -7,6 +7,7 @@ import ( "go.opentelemetry.io/otel/trace/noop" ) +// Tracer is a wrapper around the OpenTelemetry Tracer interface. type Tracer struct { trace.Tracer }