Initial import — snapshot from admin host /srv/gosec/gsc-ops-api
This repo had no version control prior to this commit. The import is a
straight snapshot of the working tree at 2026-05-03; the deployed
binary on fihelvop01 was being rebuilt from this source via `make
build` + scp into place, with no upstream review path.
The snapshot already includes one in-flight fix made on 2026-05-03 to
internal/service/persona.go:GetSelfModel — the handler queried
`source` and `strength` columns plus an `is_active = true` filter on
persona.persona_commitments, none of which exist on that table (its
shape is session-bound commitments with `status`, `commitment_meta`,
etc.). The query returned a 500 every time SynapseHub bootstrapped a
persona's self-model, dropping the IdentityConstraints / Commitments /
ConscienceStandards layer from the assembled prompt. The patched
query reads existing columns only (commitment_text, commitment_type),
filters on `status='active'`, and synthesises Source="learned" /
Strength=1.0 to keep the SelfModel response shape stable for callers.
Verified live: `GET /api/v1/personas/70f7cfd9-.../self-model` now
returns 200 with `{identityConstraints:[],commitments:[],
conscienceStandards:[]}` instead of 500.
Future changes go through PRs against this repo — no more bin-only
deploys.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
65
pkg/types/errors.go
Normal file
65
pkg/types/errors.go
Normal file
@@ -0,0 +1,65 @@
|
||||
package types
|
||||
|
||||
import "fmt"
|
||||
|
||||
// Standard error codes for REST API responses
|
||||
const (
|
||||
CodeBadRequest = "BAD_REQUEST"
|
||||
CodeUnauthorized = "UNAUTHORIZED"
|
||||
CodeForbidden = "FORBIDDEN"
|
||||
CodeNotFound = "NOT_FOUND"
|
||||
CodeConflict = "CONFLICT"
|
||||
CodeValidation = "VALIDATION_ERROR"
|
||||
CodeInternal = "INTERNAL_ERROR"
|
||||
CodeServiceUnavail = "SERVICE_UNAVAILABLE"
|
||||
CodeTimeout = "TIMEOUT"
|
||||
)
|
||||
|
||||
// APIError represents a structured REST API error
|
||||
type APIError struct {
|
||||
Code string `json:"code"`
|
||||
Message string `json:"message"`
|
||||
RequestID string `json:"requestId,omitempty"`
|
||||
Detail string `json:"detail,omitempty"`
|
||||
Status int `json:"-"`
|
||||
}
|
||||
|
||||
func (e *APIError) Error() string {
|
||||
return fmt.Sprintf("[%s] %s", e.Code, e.Message)
|
||||
}
|
||||
|
||||
func NewBadRequest(msg string) *APIError {
|
||||
return &APIError{Code: CodeBadRequest, Message: msg, Status: 400}
|
||||
}
|
||||
|
||||
func NewUnauthorized(msg string) *APIError {
|
||||
return &APIError{Code: CodeUnauthorized, Message: msg, Status: 401}
|
||||
}
|
||||
|
||||
func NewForbidden(msg string) *APIError {
|
||||
return &APIError{Code: CodeForbidden, Message: msg, Status: 403}
|
||||
}
|
||||
|
||||
func NewNotFound(msg string) *APIError {
|
||||
return &APIError{Code: CodeNotFound, Message: msg, Status: 404}
|
||||
}
|
||||
|
||||
func NewConflict(msg string) *APIError {
|
||||
return &APIError{Code: CodeConflict, Message: msg, Status: 409}
|
||||
}
|
||||
|
||||
func NewValidation(msg string) *APIError {
|
||||
return &APIError{Code: CodeValidation, Message: msg, Status: 422}
|
||||
}
|
||||
|
||||
func NewInternal(msg string) *APIError {
|
||||
return &APIError{Code: CodeInternal, Message: msg, Status: 500}
|
||||
}
|
||||
|
||||
func NewServiceUnavailable(msg string) *APIError {
|
||||
return &APIError{Code: CodeServiceUnavail, Message: msg, Status: 503}
|
||||
}
|
||||
|
||||
func NewTimeout(msg string) *APIError {
|
||||
return &APIError{Code: CodeTimeout, Message: msg, Status: 504}
|
||||
}
|
||||
396
pkg/types/models.go
Normal file
396
pkg/types/models.go
Normal file
@@ -0,0 +1,396 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
// LDAPUser represents a FreeIPA user
|
||||
type LDAPUser struct {
|
||||
UID string `json:"uid"`
|
||||
FirstName string `json:"firstName"`
|
||||
LastName string `json:"lastName"`
|
||||
DisplayName string `json:"displayName"`
|
||||
Email string `json:"email"`
|
||||
Phone string `json:"phone,omitempty"`
|
||||
Title string `json:"title,omitempty"`
|
||||
Disabled bool `json:"disabled"`
|
||||
Groups []string `json:"groups,omitempty"`
|
||||
Shell string `json:"shell,omitempty"`
|
||||
HomeDir string `json:"homeDir,omitempty"`
|
||||
|
||||
// Extended GoSec service attributes grouped by domain
|
||||
Services map[string]map[string]interface{} `json:"services,omitempty"`
|
||||
ObjectClasses []string `json:"objectClasses,omitempty"`
|
||||
}
|
||||
|
||||
// LDAPUserCreate is the request body for creating a user
|
||||
type LDAPUserCreate struct {
|
||||
UID string `json:"uid" validate:"required"`
|
||||
FirstName string `json:"firstName" validate:"required"`
|
||||
LastName string `json:"lastName" validate:"required"`
|
||||
Email string `json:"email"`
|
||||
Password string `json:"password,omitempty"`
|
||||
Phone string `json:"phone,omitempty"`
|
||||
Title string `json:"title,omitempty"`
|
||||
Shell string `json:"shell,omitempty"`
|
||||
Services map[string]map[string]interface{} `json:"services,omitempty"`
|
||||
}
|
||||
|
||||
// LDAPUserUpdate is the request body for updating a user
|
||||
type LDAPUserUpdate struct {
|
||||
FirstName *string `json:"firstName,omitempty"`
|
||||
LastName *string `json:"lastName,omitempty"`
|
||||
Email *string `json:"email,omitempty"`
|
||||
Phone *string `json:"phone,omitempty"`
|
||||
Title *string `json:"title,omitempty"`
|
||||
Shell *string `json:"shell,omitempty"`
|
||||
Disabled *bool `json:"disabled,omitempty"`
|
||||
Services map[string]map[string]interface{} `json:"services,omitempty"`
|
||||
}
|
||||
|
||||
// LDAPGroup represents a FreeIPA group
|
||||
type LDAPGroup struct {
|
||||
CN string `json:"cn"`
|
||||
Description string `json:"description,omitempty"`
|
||||
Members []string `json:"members,omitempty"`
|
||||
GIDNumber string `json:"gidNumber,omitempty"`
|
||||
}
|
||||
|
||||
// LDAPGroupCreate is the request body for creating a group
|
||||
type LDAPGroupCreate struct {
|
||||
CN string `json:"cn" validate:"required"`
|
||||
Description string `json:"description,omitempty"`
|
||||
}
|
||||
|
||||
// LDAPGroupUpdate is the request body for updating a group
|
||||
type LDAPGroupUpdate struct {
|
||||
Description *string `json:"description,omitempty"`
|
||||
}
|
||||
|
||||
// LDAPGroupMemberAdd is the request body for adding members
|
||||
type LDAPGroupMemberAdd struct {
|
||||
Members []string `json:"members" validate:"required"`
|
||||
}
|
||||
|
||||
// PasswordReset is the request body for resetting a password
|
||||
type PasswordReset struct {
|
||||
NewPassword string `json:"newPassword" validate:"required"`
|
||||
}
|
||||
|
||||
// DNSZone represents a PowerDNS zone
|
||||
type DNSZone struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Kind string `json:"kind"`
|
||||
DNSSec bool `json:"dnssec"`
|
||||
Serial int64 `json:"serial"`
|
||||
NotifiedSerial int64 `json:"notifiedSerial"`
|
||||
Records []DNSRecord `json:"records,omitempty"`
|
||||
SOAEdit string `json:"soaEdit,omitempty"`
|
||||
SOAEditAPI string `json:"soaEditApi,omitempty"`
|
||||
}
|
||||
|
||||
// DNSRecord represents a DNS resource record set
|
||||
type DNSRecord struct {
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
TTL int `json:"ttl"`
|
||||
Records []DNSRecordEntry `json:"records"`
|
||||
Comments []DNSRecordComment `json:"comments,omitempty"`
|
||||
}
|
||||
|
||||
// DNSRecordEntry represents a single record within an RRset
|
||||
type DNSRecordEntry struct {
|
||||
Content string `json:"content"`
|
||||
Disabled bool `json:"disabled"`
|
||||
}
|
||||
|
||||
// DNSRecordComment represents a comment on an RRset
|
||||
type DNSRecordComment struct {
|
||||
Content string `json:"content"`
|
||||
Account string `json:"account"`
|
||||
ModifiedAt int64 `json:"modified_at"`
|
||||
}
|
||||
|
||||
// DNSZoneCreate is the request body for creating a zone
|
||||
type DNSZoneCreate struct {
|
||||
Name string `json:"name" validate:"required"`
|
||||
Kind string `json:"kind"`
|
||||
Nameservers []string `json:"nameservers"`
|
||||
Masters []string `json:"masters,omitempty"`
|
||||
}
|
||||
|
||||
// DNSZoneUpdate is the request body for updating zone metadata
|
||||
type DNSZoneUpdate struct {
|
||||
Kind *string `json:"kind,omitempty"`
|
||||
Masters []string `json:"masters,omitempty"`
|
||||
}
|
||||
|
||||
// DNSRecordChange is the request body for creating/updating/deleting records
|
||||
type DNSRecordChange struct {
|
||||
Name string `json:"name" validate:"required"`
|
||||
Type string `json:"type" validate:"required"`
|
||||
TTL int `json:"ttl"`
|
||||
ChangeType string `json:"changetype" validate:"required"`
|
||||
Records []DNSRecordEntry `json:"records"`
|
||||
}
|
||||
|
||||
// DomainSetup is the request body for orchestrated domain setup
|
||||
type DomainSetup struct {
|
||||
Domain string `json:"domain" validate:"required"`
|
||||
MXHost string `json:"mxHost,omitempty"`
|
||||
DKIMKey string `json:"dkimKey,omitempty"`
|
||||
SPFIncludes []string `json:"spfIncludes,omitempty"`
|
||||
}
|
||||
|
||||
// DomainVerify is the request body for domain verification
|
||||
type DomainVerify struct {
|
||||
Domain string `json:"domain" validate:"required"`
|
||||
}
|
||||
|
||||
// DomainVerifyResult is the response for domain verification
|
||||
type DomainVerifyResult struct {
|
||||
Domain string `json:"domain"`
|
||||
Results map[string]string `json:"results"`
|
||||
AllOK bool `json:"allOk"`
|
||||
}
|
||||
|
||||
// Tenant represents a database tenant record
|
||||
type Tenant struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
CustomerID uuid.UUID `json:"customerId"`
|
||||
Code string `json:"code"`
|
||||
Name string `json:"name"`
|
||||
DisplayName *string `json:"displayName,omitempty"`
|
||||
Domain *string `json:"domain,omitempty"`
|
||||
LogoURL *string `json:"logoUrl,omitempty"`
|
||||
PrimaryColor *string `json:"primaryColor,omitempty"`
|
||||
MaxUsers *int `json:"maxUsers,omitempty"`
|
||||
MaxStorageGB *int `json:"maxStorageGb,omitempty"`
|
||||
MaxRecordingHours *int `json:"maxRecordingHours,omitempty"`
|
||||
IsActive *bool `json:"isActive"`
|
||||
Metadata map[string]interface{} `json:"metadata,omitempty"`
|
||||
CreatedAt *time.Time `json:"createdAt,omitempty"`
|
||||
UpdatedAt *time.Time `json:"updatedAt,omitempty"`
|
||||
}
|
||||
|
||||
// TenantCreate is the request body for creating a tenant
|
||||
type TenantCreate struct {
|
||||
CustomerID uuid.UUID `json:"customerId" validate:"required"`
|
||||
Code string `json:"code" validate:"required"`
|
||||
Name string `json:"name" validate:"required"`
|
||||
DisplayName string `json:"displayName,omitempty"`
|
||||
Domain string `json:"domain,omitempty"`
|
||||
LogoURL string `json:"logoUrl,omitempty"`
|
||||
PrimaryColor string `json:"primaryColor,omitempty"`
|
||||
MaxUsers *int `json:"maxUsers,omitempty"`
|
||||
MaxStorageGB *int `json:"maxStorageGb,omitempty"`
|
||||
MaxRecordingHours *int `json:"maxRecordingHours,omitempty"`
|
||||
Metadata map[string]interface{} `json:"metadata,omitempty"`
|
||||
}
|
||||
|
||||
// TenantUpdate is the request body for updating a tenant
|
||||
type TenantUpdate struct {
|
||||
Name *string `json:"name,omitempty"`
|
||||
DisplayName *string `json:"displayName,omitempty"`
|
||||
Domain *string `json:"domain,omitempty"`
|
||||
LogoURL *string `json:"logoUrl,omitempty"`
|
||||
PrimaryColor *string `json:"primaryColor,omitempty"`
|
||||
MaxUsers *int `json:"maxUsers,omitempty"`
|
||||
MaxStorageGB *int `json:"maxStorageGb,omitempty"`
|
||||
MaxRecordingHours *int `json:"maxRecordingHours,omitempty"`
|
||||
IsActive *bool `json:"isActive,omitempty"`
|
||||
Metadata map[string]interface{} `json:"metadata,omitempty"`
|
||||
}
|
||||
|
||||
// DBUser represents a database user record
|
||||
type DBUser struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
GscSID string `json:"gscsid"`
|
||||
FirstName *string `json:"firstName,omitempty"`
|
||||
LastName *string `json:"lastName,omitempty"`
|
||||
DisplayName *string `json:"displayName,omitempty"`
|
||||
Email *string `json:"email,omitempty"`
|
||||
Timezone *string `json:"timezone,omitempty"`
|
||||
Locale *string `json:"locale,omitempty"`
|
||||
Status *string `json:"status,omitempty"`
|
||||
LastLoginAt *time.Time `json:"lastLoginAt,omitempty"`
|
||||
LastActivityAt *time.Time `json:"lastActivityAt,omitempty"`
|
||||
Metadata map[string]interface{} `json:"metadata,omitempty"`
|
||||
CreatedAt *time.Time `json:"createdAt,omitempty"`
|
||||
UpdatedAt *time.Time `json:"updatedAt,omitempty"`
|
||||
}
|
||||
|
||||
// DBUserCreate is the request body for creating a user record
|
||||
type DBUserCreate struct {
|
||||
GscSID string `json:"gscsid" validate:"required"`
|
||||
FirstName string `json:"firstName,omitempty"`
|
||||
LastName string `json:"lastName,omitempty"`
|
||||
DisplayName string `json:"displayName,omitempty"`
|
||||
Email string `json:"email,omitempty"`
|
||||
Timezone string `json:"timezone,omitempty"`
|
||||
Locale string `json:"locale,omitempty"`
|
||||
Metadata map[string]interface{} `json:"metadata,omitempty"`
|
||||
}
|
||||
|
||||
// DBUserUpdate is the request body for updating a user record
|
||||
type DBUserUpdate struct {
|
||||
Timezone *string `json:"timezone,omitempty"`
|
||||
Locale *string `json:"locale,omitempty"`
|
||||
Status *string `json:"status,omitempty"`
|
||||
LastLoginAt *time.Time `json:"lastLoginAt,omitempty"`
|
||||
LastActivityAt *time.Time `json:"lastActivityAt,omitempty"`
|
||||
Metadata map[string]interface{} `json:"metadata,omitempty"`
|
||||
}
|
||||
|
||||
// Certificate represents an EJBCA certificate
|
||||
type Certificate struct {
|
||||
SerialNumber string `json:"serialNumber"`
|
||||
SubjectDN string `json:"subjectDn"`
|
||||
IssuerDN string `json:"issuerDn"`
|
||||
Status string `json:"status"`
|
||||
NotBefore time.Time `json:"notBefore"`
|
||||
NotAfter time.Time `json:"notAfter"`
|
||||
KeyAlgorithm string `json:"keyAlgorithm,omitempty"`
|
||||
CAName string `json:"caName,omitempty"`
|
||||
CertProfileID int `json:"certProfileId,omitempty"`
|
||||
}
|
||||
|
||||
// CertRequest is the request body for requesting a certificate
|
||||
type CertRequest struct {
|
||||
SubjectDN string `json:"subjectDn" validate:"required"`
|
||||
CAName string `json:"caName" validate:"required"`
|
||||
CertProfileName string `json:"certProfileName" validate:"required"`
|
||||
EndEntityName string `json:"endEntityName" validate:"required"`
|
||||
KeyAlgorithm string `json:"keyAlgorithm,omitempty"`
|
||||
SANs []string `json:"sans,omitempty"`
|
||||
}
|
||||
|
||||
// CertRenew is the request body for renewing a certificate
|
||||
type CertRenew struct {
|
||||
CSR string `json:"csr,omitempty"`
|
||||
}
|
||||
|
||||
// CertRevoke is the request body for revoking a certificate
|
||||
type CertRevoke struct {
|
||||
Reason string `json:"reason"`
|
||||
IssuerDN string `json:"issuerDn"`
|
||||
}
|
||||
|
||||
// LDAPEntity represents a generic LDAP entity (tenant, policy, key, etc.)
|
||||
type LDAPEntity struct {
|
||||
DN string `json:"dn"`
|
||||
Type string `json:"type"`
|
||||
RDN string `json:"rdn"`
|
||||
ObjectClasses []string `json:"objectClasses,omitempty"`
|
||||
Attributes map[string]interface{} `json:"attributes"`
|
||||
}
|
||||
|
||||
// LDAPEntityCreate is the request body for creating an entity
|
||||
type LDAPEntityCreate struct {
|
||||
Attributes map[string]interface{} `json:"attributes" validate:"required"`
|
||||
}
|
||||
|
||||
// LDAPEntityUpdate is the request body for updating an entity
|
||||
type LDAPEntityUpdate struct {
|
||||
Attributes map[string]interface{} `json:"attributes" validate:"required"`
|
||||
}
|
||||
|
||||
// PGPKey represents a Hockeypuck PGP key
|
||||
type PGPKey struct {
|
||||
KeyID string `json:"keyId"`
|
||||
Fingerprint string `json:"fingerprint"`
|
||||
Algorithm string `json:"algorithm,omitempty"`
|
||||
Length int `json:"length,omitempty"`
|
||||
Created string `json:"created,omitempty"`
|
||||
Expires string `json:"expires,omitempty"`
|
||||
UIDs []string `json:"uids,omitempty"`
|
||||
ArmoredKey string `json:"armoredKey,omitempty"`
|
||||
}
|
||||
|
||||
// PGPKeyUpload is the request body for uploading a PGP key
|
||||
type PGPKeyUpload struct {
|
||||
KeyText string `json:"keyText" validate:"required"`
|
||||
}
|
||||
|
||||
// CardDAVPrincipal represents a sabre/dav principal
|
||||
type CardDAVPrincipal struct {
|
||||
ID int `json:"id"`
|
||||
URI string `json:"uri"`
|
||||
Email string `json:"email,omitempty"`
|
||||
DisplayName string `json:"displayName,omitempty"`
|
||||
}
|
||||
|
||||
// CardDAVPrincipalCreate is the request body for creating a principal
|
||||
type CardDAVPrincipalCreate struct {
|
||||
Username string `json:"username" validate:"required"`
|
||||
Email string `json:"email,omitempty"`
|
||||
DisplayName string `json:"displayName,omitempty"`
|
||||
}
|
||||
|
||||
// AddressBook represents a sabre/dav address book
|
||||
type AddressBook struct {
|
||||
ID int `json:"id"`
|
||||
PrincipalURI string `json:"principalUri"`
|
||||
DisplayName string `json:"displayName"`
|
||||
URI string `json:"uri"`
|
||||
Description string `json:"description,omitempty"`
|
||||
SyncToken int `json:"syncToken"`
|
||||
}
|
||||
|
||||
// AddressBookCreate is the request body for creating an address book
|
||||
type AddressBookCreate struct {
|
||||
PrincipalURI string `json:"principalUri" validate:"required"`
|
||||
DisplayName string `json:"displayName" validate:"required"`
|
||||
URI string `json:"uri" validate:"required"`
|
||||
Description string `json:"description,omitempty"`
|
||||
}
|
||||
|
||||
// AddressBookUpdate is the request body for updating an address book
|
||||
type AddressBookUpdate struct {
|
||||
DisplayName *string `json:"displayName,omitempty"`
|
||||
Description *string `json:"description,omitempty"`
|
||||
}
|
||||
|
||||
// Contact represents a sabre/dav contact (card)
|
||||
type Contact struct {
|
||||
ID int `json:"id"`
|
||||
AddressBookID int `json:"addressbookId"`
|
||||
CardData string `json:"cardData,omitempty"`
|
||||
URI string `json:"uri"`
|
||||
LastModified int `json:"lastModified,omitempty"`
|
||||
ETag string `json:"etag"`
|
||||
Size int `json:"size"`
|
||||
}
|
||||
|
||||
// ContactCreate is the request body for creating a contact
|
||||
type ContactCreate struct {
|
||||
URI string `json:"uri" validate:"required"`
|
||||
CardData string `json:"cardData" validate:"required"`
|
||||
}
|
||||
|
||||
// ContactUpdate is the request body for updating a contact
|
||||
type ContactUpdate struct {
|
||||
CardData string `json:"cardData" validate:"required"`
|
||||
}
|
||||
|
||||
// ListParams represents common query parameters for list endpoints
|
||||
type ListParams struct {
|
||||
Limit int `query:"limit"`
|
||||
Offset int `query:"offset"`
|
||||
Search string `query:"search"`
|
||||
Status string `query:"status"`
|
||||
}
|
||||
|
||||
// DefaultListParams returns list params with defaults applied
|
||||
func DefaultListParams(p ListParams) ListParams {
|
||||
if p.Limit <= 0 || p.Limit > 100 {
|
||||
p.Limit = 50
|
||||
}
|
||||
if p.Offset < 0 {
|
||||
p.Offset = 0
|
||||
}
|
||||
return p
|
||||
}
|
||||
283
pkg/types/pbx.go
Normal file
283
pkg/types/pbx.go
Normal file
@@ -0,0 +1,283 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
// PBXTrunk represents a SIP trunk configuration
|
||||
type PBXTrunk struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
TenantID uuid.UUID `json:"tenantId"`
|
||||
ProviderID *uuid.UUID `json:"providerId,omitempty"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description,omitempty"`
|
||||
TrunkType string `json:"trunkType"`
|
||||
Status string `json:"status"`
|
||||
Host string `json:"host"`
|
||||
Port int `json:"port"`
|
||||
Transport string `json:"transport"`
|
||||
Username string `json:"username,omitempty"`
|
||||
AuthRealm string `json:"authRealm,omitempty"`
|
||||
FromDomain string `json:"fromDomain,omitempty"`
|
||||
FromUser string `json:"fromUser,omitempty"`
|
||||
Register bool `json:"register"`
|
||||
Codecs []string `json:"codecs"`
|
||||
DtmfMode string `json:"dtmfMode"`
|
||||
NatMode string `json:"natMode,omitempty"`
|
||||
MaxChannels *int `json:"maxChannels,omitempty"`
|
||||
CurrentChannels *int `json:"currentChannels,omitempty"`
|
||||
OutboundCallerIDName string `json:"outboundCallerIdName,omitempty"`
|
||||
OutboundCallerIDNum string `json:"outboundCallerIdNumber,omitempty"`
|
||||
Priority *int `json:"priority,omitempty"`
|
||||
DIDCount int `json:"didCount,omitempty"`
|
||||
CreatedAt *time.Time `json:"createdAt,omitempty"`
|
||||
UpdatedAt *time.Time `json:"updatedAt,omitempty"`
|
||||
}
|
||||
|
||||
// PBXTrunkCreate is the request body for creating a trunk
|
||||
type PBXTrunkCreate struct {
|
||||
TenantID uuid.UUID `json:"tenantId" validate:"required"`
|
||||
ProviderID *uuid.UUID `json:"providerId,omitempty"`
|
||||
Name string `json:"name" validate:"required"`
|
||||
Description string `json:"description,omitempty"`
|
||||
Host string `json:"host" validate:"required"`
|
||||
Port int `json:"port,omitempty"`
|
||||
Transport string `json:"transport,omitempty"`
|
||||
Username string `json:"username,omitempty"`
|
||||
Password string `json:"password,omitempty"`
|
||||
AuthRealm string `json:"authRealm,omitempty"`
|
||||
FromDomain string `json:"fromDomain,omitempty"`
|
||||
FromUser string `json:"fromUser,omitempty"`
|
||||
Register bool `json:"register"`
|
||||
Codecs []string `json:"codecs,omitempty"`
|
||||
DtmfMode string `json:"dtmfMode,omitempty"`
|
||||
NatMode string `json:"natMode,omitempty"`
|
||||
MaxChannels *int `json:"maxChannels,omitempty"`
|
||||
OutboundCallerIDName string `json:"outboundCallerIdName,omitempty"`
|
||||
OutboundCallerIDNum string `json:"outboundCallerIdNumber,omitempty"`
|
||||
}
|
||||
|
||||
// PBXTrunkUpdate is the request body for updating a trunk
|
||||
type PBXTrunkUpdate struct {
|
||||
Name *string `json:"name,omitempty"`
|
||||
Description *string `json:"description,omitempty"`
|
||||
Host *string `json:"host,omitempty"`
|
||||
Port *int `json:"port,omitempty"`
|
||||
Transport *string `json:"transport,omitempty"`
|
||||
Username *string `json:"username,omitempty"`
|
||||
Password *string `json:"password,omitempty"`
|
||||
AuthRealm *string `json:"authRealm,omitempty"`
|
||||
FromDomain *string `json:"fromDomain,omitempty"`
|
||||
FromUser *string `json:"fromUser,omitempty"`
|
||||
Register *bool `json:"register,omitempty"`
|
||||
Codecs []string `json:"codecs,omitempty"`
|
||||
DtmfMode *string `json:"dtmfMode,omitempty"`
|
||||
NatMode *string `json:"natMode,omitempty"`
|
||||
MaxChannels *int `json:"maxChannels,omitempty"`
|
||||
OutboundCallerIDName *string `json:"outboundCallerIdName,omitempty"`
|
||||
OutboundCallerIDNum *string `json:"outboundCallerIdNumber,omitempty"`
|
||||
Status *string `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// PBXTrunkDID represents a DID number assigned to a trunk
|
||||
type PBXTrunkDID struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
TrunkID uuid.UUID `json:"trunkId"`
|
||||
TenantID uuid.UUID `json:"tenantId"`
|
||||
DIDNumber string `json:"didNumber"`
|
||||
Description string `json:"description,omitempty"`
|
||||
DestinationType string `json:"destinationType,omitempty"`
|
||||
DestinationID *uuid.UUID `json:"destinationId,omitempty"`
|
||||
IsActive bool `json:"isActive"`
|
||||
CreatedAt *time.Time `json:"createdAt,omitempty"`
|
||||
}
|
||||
|
||||
// PBXTrunkDIDCreate is the request body for adding a DID to a trunk
|
||||
type PBXTrunkDIDCreate struct {
|
||||
DIDNumber string `json:"didNumber" validate:"required"`
|
||||
TenantID uuid.UUID `json:"tenantId" validate:"required"`
|
||||
Description string `json:"description,omitempty"`
|
||||
DestinationType string `json:"destinationType,omitempty"`
|
||||
DestinationID *uuid.UUID `json:"destinationId,omitempty"`
|
||||
}
|
||||
|
||||
// PBXExtension represents a PBX extension
|
||||
type PBXExtension struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
TenantID uuid.UUID `json:"tenantId"`
|
||||
UserID *uuid.UUID `json:"userId,omitempty"`
|
||||
Extension string `json:"extension"`
|
||||
Name string `json:"name"`
|
||||
ExtensionType string `json:"extensionType"`
|
||||
CallerIDName string `json:"callerIdName,omitempty"`
|
||||
CallerIDNumber string `json:"callerIdNumber,omitempty"`
|
||||
OutboundCallerIDNumber string `json:"outboundCallerIdNumber,omitempty"`
|
||||
SIPUsername string `json:"sipUsername,omitempty"`
|
||||
Transport string `json:"transport"`
|
||||
Codecs []string `json:"codecs"`
|
||||
VoicemailEnabled bool `json:"voicemailEnabled"`
|
||||
IsActive bool `json:"isActive"`
|
||||
CreatedAt *time.Time `json:"createdAt,omitempty"`
|
||||
UpdatedAt *time.Time `json:"updatedAt,omitempty"`
|
||||
}
|
||||
|
||||
// PBXExtensionCreate is the request body for creating an extension
|
||||
type PBXExtensionCreate struct {
|
||||
TenantID uuid.UUID `json:"tenantId" validate:"required"`
|
||||
UserID *uuid.UUID `json:"userId,omitempty"`
|
||||
Extension string `json:"extension" validate:"required"`
|
||||
Name string `json:"name" validate:"required"`
|
||||
ExtensionType string `json:"extensionType,omitempty"`
|
||||
CallerIDName string `json:"callerIdName,omitempty"`
|
||||
CallerIDNumber string `json:"callerIdNumber,omitempty"`
|
||||
OutboundCallerIDNumber string `json:"outboundCallerIdNumber,omitempty"`
|
||||
SIPUsername string `json:"sipUsername,omitempty"`
|
||||
SIPPassword string `json:"sipPassword,omitempty"`
|
||||
Transport string `json:"transport,omitempty"`
|
||||
Codecs []string `json:"codecs,omitempty"`
|
||||
VoicemailEnabled bool `json:"voicemailEnabled"`
|
||||
}
|
||||
|
||||
// PBXExtensionUpdate is the request body for updating an extension
|
||||
type PBXExtensionUpdate struct {
|
||||
Name *string `json:"name,omitempty"`
|
||||
CallerIDName *string `json:"callerIdName,omitempty"`
|
||||
CallerIDNumber *string `json:"callerIdNumber,omitempty"`
|
||||
OutboundCallerIDNumber *string `json:"outboundCallerIdNumber,omitempty"`
|
||||
SIPPassword *string `json:"sipPassword,omitempty"`
|
||||
Codecs []string `json:"codecs,omitempty"`
|
||||
VoicemailEnabled *bool `json:"voicemailEnabled,omitempty"`
|
||||
IsActive *bool `json:"isActive,omitempty"`
|
||||
}
|
||||
|
||||
// PBXInboundRoute represents an inbound call route
|
||||
type PBXInboundRoute struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
TenantID uuid.UUID `json:"tenantId"`
|
||||
Name string `json:"name"`
|
||||
DIDNumber string `json:"didNumber,omitempty"`
|
||||
DestinationType string `json:"destinationType"`
|
||||
DestinationID *uuid.UUID `json:"destinationId,omitempty"`
|
||||
DestinationData string `json:"destinationData,omitempty"`
|
||||
Priority int `json:"priority"`
|
||||
IsActive bool `json:"isActive"`
|
||||
TrunkID *uuid.UUID `json:"trunkId,omitempty"`
|
||||
CreatedAt *time.Time `json:"createdAt,omitempty"`
|
||||
UpdatedAt *time.Time `json:"updatedAt,omitempty"`
|
||||
}
|
||||
|
||||
// PBXInboundRouteCreate is the request body for creating an inbound route
|
||||
type PBXInboundRouteCreate struct {
|
||||
TenantID uuid.UUID `json:"tenantId" validate:"required"`
|
||||
Name string `json:"name" validate:"required"`
|
||||
DIDNumber string `json:"didNumber,omitempty"`
|
||||
DestinationType string `json:"destinationType" validate:"required"`
|
||||
DestinationID *uuid.UUID `json:"destinationId,omitempty"`
|
||||
DestinationData string `json:"destinationData,omitempty"`
|
||||
Priority int `json:"priority,omitempty"`
|
||||
TrunkID *uuid.UUID `json:"trunkId,omitempty"`
|
||||
}
|
||||
|
||||
// PBXInboundRouteUpdate is the request body for updating an inbound route
|
||||
type PBXInboundRouteUpdate struct {
|
||||
Name *string `json:"name,omitempty"`
|
||||
DIDNumber *string `json:"didNumber,omitempty"`
|
||||
DestinationType *string `json:"destinationType,omitempty"`
|
||||
DestinationID *uuid.UUID `json:"destinationId,omitempty"`
|
||||
DestinationData *string `json:"destinationData,omitempty"`
|
||||
Priority *int `json:"priority,omitempty"`
|
||||
IsActive *bool `json:"isActive,omitempty"`
|
||||
TrunkID *uuid.UUID `json:"trunkId,omitempty"`
|
||||
}
|
||||
|
||||
// PBXOutboundRoute represents an outbound call route
|
||||
type PBXOutboundRoute struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
TenantID uuid.UUID `json:"tenantId"`
|
||||
Name string `json:"name"`
|
||||
Priority int `json:"priority"`
|
||||
DialPatterns []string `json:"dialPatterns"`
|
||||
Prepend string `json:"prepend,omitempty"`
|
||||
Prefix string `json:"prefix,omitempty"`
|
||||
StripDigits int `json:"stripDigits"`
|
||||
OverrideCallerID bool `json:"overrideCallerId"`
|
||||
CallerIDName string `json:"callerIdName,omitempty"`
|
||||
CallerIDNumber string `json:"callerIdNumber,omitempty"`
|
||||
IsEmergency bool `json:"isEmergency"`
|
||||
IsActive bool `json:"isActive"`
|
||||
Trunks []PBXOutboundRouteTrunk `json:"trunks,omitempty"`
|
||||
CreatedAt *time.Time `json:"createdAt,omitempty"`
|
||||
UpdatedAt *time.Time `json:"updatedAt,omitempty"`
|
||||
}
|
||||
|
||||
// PBXOutboundRouteTrunk represents a trunk priority in an outbound route
|
||||
type PBXOutboundRouteTrunk struct {
|
||||
TrunkID uuid.UUID `json:"trunkId"`
|
||||
TrunkName string `json:"trunkName,omitempty"`
|
||||
Priority int `json:"priority"`
|
||||
}
|
||||
|
||||
// PBXOutboundRouteCreate is the request body for creating an outbound route
|
||||
type PBXOutboundRouteCreate struct {
|
||||
TenantID uuid.UUID `json:"tenantId" validate:"required"`
|
||||
Name string `json:"name" validate:"required"`
|
||||
Priority int `json:"priority,omitempty"`
|
||||
DialPatterns []string `json:"dialPatterns" validate:"required"`
|
||||
Prepend string `json:"prepend,omitempty"`
|
||||
Prefix string `json:"prefix,omitempty"`
|
||||
StripDigits int `json:"stripDigits,omitempty"`
|
||||
OverrideCallerID bool `json:"overrideCallerId"`
|
||||
CallerIDName string `json:"callerIdName,omitempty"`
|
||||
CallerIDNumber string `json:"callerIdNumber,omitempty"`
|
||||
IsEmergency bool `json:"isEmergency"`
|
||||
Trunks []PBXOutboundRouteTrunk `json:"trunks,omitempty"`
|
||||
}
|
||||
|
||||
// PBXOutboundRouteUpdate is the request body for updating an outbound route
|
||||
type PBXOutboundRouteUpdate struct {
|
||||
Name *string `json:"name,omitempty"`
|
||||
Priority *int `json:"priority,omitempty"`
|
||||
DialPatterns []string `json:"dialPatterns,omitempty"`
|
||||
Prepend *string `json:"prepend,omitempty"`
|
||||
Prefix *string `json:"prefix,omitempty"`
|
||||
StripDigits *int `json:"stripDigits,omitempty"`
|
||||
OverrideCallerID *bool `json:"overrideCallerId,omitempty"`
|
||||
CallerIDName *string `json:"callerIdName,omitempty"`
|
||||
CallerIDNumber *string `json:"callerIdNumber,omitempty"`
|
||||
IsEmergency *bool `json:"isEmergency,omitempty"`
|
||||
IsActive *bool `json:"isActive,omitempty"`
|
||||
Trunks []PBXOutboundRouteTrunk `json:"trunks,omitempty"`
|
||||
}
|
||||
|
||||
// PBXStatus represents the overall PBX system status
|
||||
type PBXStatus struct {
|
||||
AsteriskServers []PBXServerStatus `json:"asteriskServers"`
|
||||
KamailioServers []PBXServerStatus `json:"kamailioServers"`
|
||||
ActiveTrunks int `json:"activeTrunks"`
|
||||
ActiveExtensions int `json:"activeExtensions"`
|
||||
ActiveCalls int `json:"activeCalls"`
|
||||
}
|
||||
|
||||
// PBXServerStatus represents a single PBX server status
|
||||
type PBXServerStatus struct {
|
||||
Host string `json:"host"`
|
||||
Status string `json:"status"`
|
||||
Uptime string `json:"uptime,omitempty"`
|
||||
Version string `json:"version,omitempty"`
|
||||
Channels int `json:"channels,omitempty"`
|
||||
}
|
||||
|
||||
// PBXReloadResult represents the result of a PBX reload operation
|
||||
type PBXReloadResult struct {
|
||||
AsteriskResults []PBXReloadServer `json:"asteriskResults"`
|
||||
KamailioResults []PBXReloadServer `json:"kamailioResults"`
|
||||
}
|
||||
|
||||
// PBXReloadServer represents a reload result for a single server
|
||||
type PBXReloadServer struct {
|
||||
Host string `json:"host"`
|
||||
Success bool `json:"success"`
|
||||
Message string `json:"message,omitempty"`
|
||||
}
|
||||
181
pkg/types/persona.go
Normal file
181
pkg/types/persona.go
Normal file
@@ -0,0 +1,181 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
// PersonaSummary is the list view of a persona
|
||||
type PersonaSummary struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
TenantID uuid.UUID `json:"tenantId"`
|
||||
Name string `json:"name"`
|
||||
Archetype *string `json:"archetype,omitempty"`
|
||||
Status string `json:"status"`
|
||||
IsDefault bool `json:"isDefault"`
|
||||
CreatedAt *time.Time `json:"createdAt,omitempty"`
|
||||
UpdatedAt *time.Time `json:"updatedAt,omitempty"`
|
||||
}
|
||||
|
||||
// PersonaConfig is the full persona configuration
|
||||
type PersonaConfig struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
TenantID uuid.UUID `json:"tenantId"`
|
||||
Name string `json:"name"`
|
||||
Archetype *string `json:"archetype,omitempty"`
|
||||
VoiceTone *string `json:"voiceTone,omitempty"`
|
||||
MBTI *string `json:"mbti,omitempty"`
|
||||
Openness *float64 `json:"openness,omitempty"`
|
||||
Conscientiousness *float64 `json:"conscientiousness,omitempty"`
|
||||
Extraversion *float64 `json:"extraversion,omitempty"`
|
||||
Agreeableness *float64 `json:"agreeableness,omitempty"`
|
||||
Neuroticism *float64 `json:"neuroticism,omitempty"`
|
||||
PositiveRules json.RawMessage `json:"positiveRules,omitempty"`
|
||||
NegativeRules json.RawMessage `json:"negativeRules,omitempty"`
|
||||
Backstory *string `json:"backstory,omitempty"`
|
||||
WorldBuilding *string `json:"worldBuilding,omitempty"`
|
||||
GuardrailsConfig json.RawMessage `json:"guardrailsConfig,omitempty"`
|
||||
TopicalRails *string `json:"topicalRails,omitempty"`
|
||||
Status string `json:"status"`
|
||||
DefaultModel *string `json:"defaultModel,omitempty"`
|
||||
Temperature *float64 `json:"temperature,omitempty"`
|
||||
MaxTokensPerTurn *int `json:"maxTokensPerTurn,omitempty"`
|
||||
MoralCare *float64 `json:"moralCare,omitempty"`
|
||||
MoralFairness *float64 `json:"moralFairness,omitempty"`
|
||||
MoralRights *float64 `json:"moralRights,omitempty"`
|
||||
MoralLoyalty *float64 `json:"moralLoyalty,omitempty"`
|
||||
MoralAuthority *float64 `json:"moralAuthority,omitempty"`
|
||||
MoralSanctity *float64 `json:"moralSanctity,omitempty"`
|
||||
IsDefault bool `json:"isDefault"`
|
||||
CreatedAt *time.Time `json:"createdAt,omitempty"`
|
||||
UpdatedAt *time.Time `json:"updatedAt,omitempty"`
|
||||
}
|
||||
|
||||
// PersonaCreate is the request body for creating a persona
|
||||
type PersonaCreate struct {
|
||||
TenantID uuid.UUID `json:"tenantId" validate:"required"`
|
||||
Name string `json:"name" validate:"required"`
|
||||
Archetype *string `json:"archetype,omitempty"`
|
||||
VoiceTone *string `json:"voiceTone,omitempty"`
|
||||
MBTI *string `json:"mbti,omitempty"`
|
||||
Openness *float64 `json:"openness,omitempty"`
|
||||
Conscientiousness *float64 `json:"conscientiousness,omitempty"`
|
||||
Extraversion *float64 `json:"extraversion,omitempty"`
|
||||
Agreeableness *float64 `json:"agreeableness,omitempty"`
|
||||
Neuroticism *float64 `json:"neuroticism,omitempty"`
|
||||
PositiveRules json.RawMessage `json:"positiveRules,omitempty"`
|
||||
NegativeRules json.RawMessage `json:"negativeRules,omitempty"`
|
||||
Backstory *string `json:"backstory,omitempty"`
|
||||
WorldBuilding *string `json:"worldBuilding,omitempty"`
|
||||
GuardrailsConfig json.RawMessage `json:"guardrailsConfig,omitempty"`
|
||||
TopicalRails *string `json:"topicalRails,omitempty"`
|
||||
DefaultModel *string `json:"defaultModel,omitempty"`
|
||||
Temperature *float64 `json:"temperature,omitempty"`
|
||||
MaxTokensPerTurn *int `json:"maxTokensPerTurn,omitempty"`
|
||||
MoralCare *float64 `json:"moralCare,omitempty"`
|
||||
MoralFairness *float64 `json:"moralFairness,omitempty"`
|
||||
MoralRights *float64 `json:"moralRights,omitempty"`
|
||||
MoralLoyalty *float64 `json:"moralLoyalty,omitempty"`
|
||||
MoralAuthority *float64 `json:"moralAuthority,omitempty"`
|
||||
MoralSanctity *float64 `json:"moralSanctity,omitempty"`
|
||||
}
|
||||
|
||||
// PersonaUpdate is the request body for updating a persona
|
||||
type PersonaUpdate struct {
|
||||
Name *string `json:"name,omitempty"`
|
||||
Archetype *string `json:"archetype,omitempty"`
|
||||
VoiceTone *string `json:"voiceTone,omitempty"`
|
||||
MBTI *string `json:"mbti,omitempty"`
|
||||
Openness *float64 `json:"openness,omitempty"`
|
||||
Conscientiousness *float64 `json:"conscientiousness,omitempty"`
|
||||
Extraversion *float64 `json:"extraversion,omitempty"`
|
||||
Agreeableness *float64 `json:"agreeableness,omitempty"`
|
||||
Neuroticism *float64 `json:"neuroticism,omitempty"`
|
||||
PositiveRules json.RawMessage `json:"positiveRules,omitempty"`
|
||||
NegativeRules json.RawMessage `json:"negativeRules,omitempty"`
|
||||
Backstory *string `json:"backstory,omitempty"`
|
||||
WorldBuilding *string `json:"worldBuilding,omitempty"`
|
||||
GuardrailsConfig json.RawMessage `json:"guardrailsConfig,omitempty"`
|
||||
TopicalRails *string `json:"topicalRails,omitempty"`
|
||||
Status *string `json:"status,omitempty"`
|
||||
DefaultModel *string `json:"defaultModel,omitempty"`
|
||||
Temperature *float64 `json:"temperature,omitempty"`
|
||||
MaxTokensPerTurn *int `json:"maxTokensPerTurn,omitempty"`
|
||||
MoralCare *float64 `json:"moralCare,omitempty"`
|
||||
MoralFairness *float64 `json:"moralFairness,omitempty"`
|
||||
MoralRights *float64 `json:"moralRights,omitempty"`
|
||||
MoralLoyalty *float64 `json:"moralLoyalty,omitempty"`
|
||||
MoralAuthority *float64 `json:"moralAuthority,omitempty"`
|
||||
MoralSanctity *float64 `json:"moralSanctity,omitempty"`
|
||||
IsDefault *bool `json:"isDefault,omitempty"`
|
||||
}
|
||||
|
||||
// SelfModelSnapshot contains identity constraints, commitments, and conscience standards
|
||||
type SelfModelSnapshot struct {
|
||||
IdentityConstraints []IdentityConstraint `json:"identityConstraints"`
|
||||
Commitments []PersonaCommitment `json:"commitments"`
|
||||
ConscienceStandards []ConscienceStandard `json:"conscienceStandards"`
|
||||
}
|
||||
|
||||
// IdentityConstraint defines a persona's behavioral boundary
|
||||
type IdentityConstraint struct {
|
||||
ConstraintType string `json:"type"`
|
||||
ConstraintText string `json:"text"`
|
||||
Description *string `json:"description,omitempty"`
|
||||
Source *string `json:"source,omitempty"`
|
||||
Strength float64 `json:"strength"`
|
||||
}
|
||||
|
||||
// PersonaCommitment defines a persona's commitment
|
||||
type PersonaCommitment struct {
|
||||
CommitmentText string `json:"text"`
|
||||
CommitmentType *string `json:"type,omitempty"`
|
||||
Source *string `json:"source,omitempty"`
|
||||
Strength float64 `json:"strength"`
|
||||
}
|
||||
|
||||
// ConscienceStandard defines a moral standard for a persona
|
||||
type ConscienceStandard struct {
|
||||
StandardText string `json:"text"`
|
||||
StandardType *string `json:"type,omitempty"`
|
||||
MoralFoundation *string `json:"moralFoundation,omitempty"`
|
||||
Strength float64 `json:"strength"`
|
||||
}
|
||||
|
||||
// Experience represents an episodic experience
|
||||
type Experience struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
EventSummary *string `json:"eventSummary,omitempty"`
|
||||
EventType *string `json:"eventType,omitempty"`
|
||||
OccurredAt *time.Time `json:"occurredAt,omitempty"`
|
||||
Place *string `json:"place,omitempty"`
|
||||
Actors *string `json:"actors,omitempty"`
|
||||
Outcome *string `json:"outcome,omitempty"`
|
||||
OutcomeDetail *string `json:"outcomeDetail,omitempty"`
|
||||
EmotionalValence *float64 `json:"emotionalValence,omitempty"`
|
||||
LessonLearned *string `json:"lessonLearned,omitempty"`
|
||||
ImportanceScore *float64 `json:"importanceScore,omitempty"`
|
||||
}
|
||||
|
||||
// MoralAssessment represents a moral assessment for a session
|
||||
type MoralAssessment struct {
|
||||
ActivatedFoundations json.RawMessage `json:"activatedFoundations,omitempty"`
|
||||
AssessmentText *string `json:"assessmentText,omitempty"`
|
||||
HasTension *bool `json:"hasTension,omitempty"`
|
||||
TensionFoundations *string `json:"tensionFoundations,omitempty"`
|
||||
ResolutionFoundation *string `json:"resolutionFoundation,omitempty"`
|
||||
Confidence *float64 `json:"confidence,omitempty"`
|
||||
}
|
||||
|
||||
// Evaluation represents a message evaluation
|
||||
type Evaluation struct {
|
||||
RoleFidelity *string `json:"roleFidelity,omitempty"`
|
||||
VoiceConsistency *string `json:"voiceConsistency,omitempty"`
|
||||
SafetyCompliance *string `json:"safetyCompliance,omitempty"`
|
||||
CharacterBreak *bool `json:"characterBreak,omitempty"`
|
||||
DriftScore *float64 `json:"driftScore,omitempty"`
|
||||
EvaluatorModel *string `json:"evaluatorModel,omitempty"`
|
||||
EvaluatedAt *time.Time `json:"evaluatedAt,omitempty"`
|
||||
}
|
||||
25
pkg/types/personal_agent.go
Normal file
25
pkg/types/personal_agent.go
Normal file
@@ -0,0 +1,25 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
// UserAgentConfig represents a user's personal AI agent configuration
|
||||
type UserAgentConfig struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
UserID uuid.UUID `json:"userId"`
|
||||
TenantID uuid.UUID `json:"tenantId"`
|
||||
Config json.RawMessage `json:"config"`
|
||||
CreatedAt *time.Time `json:"createdAt,omitempty"`
|
||||
UpdatedAt *time.Time `json:"updatedAt,omitempty"`
|
||||
}
|
||||
|
||||
// UserAgentConfigUpsert is the request body for creating/updating a user agent config
|
||||
type UserAgentConfigUpsert struct {
|
||||
UserID uuid.UUID `json:"userId" validate:"required"`
|
||||
TenantID uuid.UUID `json:"tenantId" validate:"required"`
|
||||
Config json.RawMessage `json:"config" validate:"required"`
|
||||
}
|
||||
46
pkg/types/response.go
Normal file
46
pkg/types/response.go
Normal file
@@ -0,0 +1,46 @@
|
||||
package types
|
||||
|
||||
// Response is the standard API response envelope
|
||||
type Response struct {
|
||||
Data interface{} `json:"data,omitempty"`
|
||||
Meta *Meta `json:"meta,omitempty"`
|
||||
Error *APIError `json:"error,omitempty"`
|
||||
RequestID string `json:"requestId,omitempty"`
|
||||
}
|
||||
|
||||
// Meta contains pagination and count metadata
|
||||
type Meta struct {
|
||||
Total int64 `json:"total"`
|
||||
Limit int `json:"limit"`
|
||||
Offset int `json:"offset"`
|
||||
}
|
||||
|
||||
// NewDataResponse creates a successful response with data
|
||||
func NewDataResponse(data interface{}, requestID string) *Response {
|
||||
return &Response{
|
||||
Data: data,
|
||||
RequestID: requestID,
|
||||
}
|
||||
}
|
||||
|
||||
// NewPagedResponse creates a successful response with data and pagination
|
||||
func NewPagedResponse(data interface{}, total int64, limit, offset int, requestID string) *Response {
|
||||
return &Response{
|
||||
Data: data,
|
||||
Meta: &Meta{
|
||||
Total: total,
|
||||
Limit: limit,
|
||||
Offset: offset,
|
||||
},
|
||||
RequestID: requestID,
|
||||
}
|
||||
}
|
||||
|
||||
// NewErrorResponse creates an error response
|
||||
func NewErrorResponse(err *APIError, requestID string) *Response {
|
||||
err.RequestID = requestID
|
||||
return &Response{
|
||||
Error: err,
|
||||
RequestID: requestID,
|
||||
}
|
||||
}
|
||||
115
pkg/types/voice_agent.go
Normal file
115
pkg/types/voice_agent.go
Normal file
@@ -0,0 +1,115 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
// VoiceAgentConfig represents a voice agent configuration
|
||||
type VoiceAgentConfig struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
TenantID uuid.UUID `json:"tenantId"`
|
||||
AgentID uuid.UUID `json:"agentId"`
|
||||
GreetingText string `json:"greetingText"`
|
||||
GoodbyeText string `json:"goodbyeText"`
|
||||
VoiceID string `json:"voiceId"`
|
||||
Language string `json:"language"`
|
||||
STTProvider *string `json:"sttProvider,omitempty"`
|
||||
STTModel *string `json:"sttModel,omitempty"`
|
||||
TTSProvider *string `json:"ttsProvider,omitempty"`
|
||||
TTSModel *string `json:"ttsModel,omitempty"`
|
||||
MaxCallDurationSeconds int `json:"maxCallDurationSeconds"`
|
||||
SilenceTimeoutSeconds int `json:"silenceTimeoutSeconds"`
|
||||
BargeInEnabled bool `json:"bargeInEnabled"`
|
||||
VADSensitivity string `json:"vadSensitivity"`
|
||||
TransferEnabled bool `json:"transferEnabled"`
|
||||
TransferNumber *string `json:"transferNumber,omitempty"`
|
||||
BusinessHoursEnabled bool `json:"businessHoursEnabled"`
|
||||
BusinessHours json.RawMessage `json:"businessHours,omitempty"`
|
||||
AfterHoursText *string `json:"afterHoursText,omitempty"`
|
||||
IsActive bool `json:"isActive"`
|
||||
CreatedAt *time.Time `json:"createdAt,omitempty"`
|
||||
UpdatedAt *time.Time `json:"updatedAt,omitempty"`
|
||||
}
|
||||
|
||||
// VoiceAgentConfigCreate is the request body for creating a voice agent config
|
||||
type VoiceAgentConfigCreate struct {
|
||||
TenantID uuid.UUID `json:"tenantId" validate:"required"`
|
||||
AgentID uuid.UUID `json:"agentId" validate:"required"`
|
||||
GreetingText string `json:"greetingText,omitempty"`
|
||||
GoodbyeText string `json:"goodbyeText,omitempty"`
|
||||
VoiceID string `json:"voiceId,omitempty"`
|
||||
Language string `json:"language,omitempty"`
|
||||
STTProvider *string `json:"sttProvider,omitempty"`
|
||||
STTModel *string `json:"sttModel,omitempty"`
|
||||
TTSProvider *string `json:"ttsProvider,omitempty"`
|
||||
TTSModel *string `json:"ttsModel,omitempty"`
|
||||
MaxCallDurationSeconds *int `json:"maxCallDurationSeconds,omitempty"`
|
||||
SilenceTimeoutSeconds *int `json:"silenceTimeoutSeconds,omitempty"`
|
||||
BargeInEnabled *bool `json:"bargeInEnabled,omitempty"`
|
||||
VADSensitivity string `json:"vadSensitivity,omitempty"`
|
||||
TransferEnabled *bool `json:"transferEnabled,omitempty"`
|
||||
TransferNumber *string `json:"transferNumber,omitempty"`
|
||||
BusinessHoursEnabled *bool `json:"businessHoursEnabled,omitempty"`
|
||||
BusinessHours json.RawMessage `json:"businessHours,omitempty"`
|
||||
AfterHoursText *string `json:"afterHoursText,omitempty"`
|
||||
}
|
||||
|
||||
// VoiceAgentConfigUpdate is the request body for updating a voice agent config
|
||||
type VoiceAgentConfigUpdate struct {
|
||||
GreetingText *string `json:"greetingText,omitempty"`
|
||||
GoodbyeText *string `json:"goodbyeText,omitempty"`
|
||||
VoiceID *string `json:"voiceId,omitempty"`
|
||||
Language *string `json:"language,omitempty"`
|
||||
STTProvider *string `json:"sttProvider,omitempty"`
|
||||
STTModel *string `json:"sttModel,omitempty"`
|
||||
TTSProvider *string `json:"ttsProvider,omitempty"`
|
||||
TTSModel *string `json:"ttsModel,omitempty"`
|
||||
MaxCallDurationSeconds *int `json:"maxCallDurationSeconds,omitempty"`
|
||||
SilenceTimeoutSeconds *int `json:"silenceTimeoutSeconds,omitempty"`
|
||||
BargeInEnabled *bool `json:"bargeInEnabled,omitempty"`
|
||||
VADSensitivity *string `json:"vadSensitivity,omitempty"`
|
||||
TransferEnabled *bool `json:"transferEnabled,omitempty"`
|
||||
TransferNumber *string `json:"transferNumber,omitempty"`
|
||||
BusinessHoursEnabled *bool `json:"businessHoursEnabled,omitempty"`
|
||||
BusinessHours json.RawMessage `json:"businessHours,omitempty"`
|
||||
AfterHoursText *string `json:"afterHoursText,omitempty"`
|
||||
IsActive *bool `json:"isActive,omitempty"`
|
||||
}
|
||||
|
||||
// VoiceSession represents a voice call session record
|
||||
type VoiceSession struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
TenantID uuid.UUID `json:"tenantId"`
|
||||
AgentID uuid.UUID `json:"agentId"`
|
||||
CallerNumber *string `json:"callerNumber,omitempty"`
|
||||
CalledNumber *string `json:"calledNumber,omitempty"`
|
||||
AsteriskCallID *uuid.UUID `json:"asteriskCallId,omitempty"`
|
||||
AgentSessionID *string `json:"agentSessionId,omitempty"`
|
||||
TotalTurns int `json:"totalTurns"`
|
||||
STTProvider *string `json:"sttProvider,omitempty"`
|
||||
TTSProvider *string `json:"ttsProvider,omitempty"`
|
||||
STTAudioSeconds *float64 `json:"sttAudioSeconds,omitempty"`
|
||||
TTSCharacters *int `json:"ttsCharacters,omitempty"`
|
||||
StartedAt *time.Time `json:"startedAt,omitempty"`
|
||||
EndedAt *time.Time `json:"endedAt,omitempty"`
|
||||
EndReason *string `json:"endReason,omitempty"`
|
||||
Metadata json.RawMessage `json:"metadata,omitempty"`
|
||||
CreatedAt *time.Time `json:"createdAt,omitempty"`
|
||||
Turns []VoiceSessionTurn `json:"turns,omitempty"`
|
||||
}
|
||||
|
||||
// VoiceSessionTurn represents a single turn in a voice session
|
||||
type VoiceSessionTurn struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
SessionID uuid.UUID `json:"sessionId"`
|
||||
TurnNumber int `json:"turnNumber"`
|
||||
Role string `json:"role"`
|
||||
Text string `json:"text"`
|
||||
STTConfidence *float64 `json:"sttConfidence,omitempty"`
|
||||
AgentLatencyMs *int `json:"agentLatencyMs,omitempty"`
|
||||
WasInterrupted bool `json:"wasInterrupted"`
|
||||
CreatedAt *time.Time `json:"createdAt,omitempty"`
|
||||
}
|
||||
Reference in New Issue
Block a user