appointmentbooking

package module
v0.1.5 Latest Latest
Warning

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

Go to latest
Published: Sep 8, 2026 License: MIT Imports: 11 Imported by: 0

README

appointment-booking

Manages schedulable service configuration, staff work calendars (blocks), and client reservations.

Main entities

  • employee_service_config: configuration of which services each professional handles (duration, price override).
  • reservation: the scheduled appointment (date/time, client, professional, service) with an FSM-enforced status.
  • workcalendar_block: one row per block of working time — WEEKLY (specific_date == 0, applies to day_of_week) or DATED (specific_date > 0, applies to that date only and opens it). Several blocks per day = the lunch break is the gap between them.
  • workcalendar_exception: one-off exceptions (personal holidays, special hours, blocked intervals).
  • workcalendar_config: the IANA timezone of a staff member's calendar (inherited by blocks and exceptions).

Documentation

Design / decoupling notes

No physical FKs to other modules:

  • reservation.client_id references a client (Directory/Clinical) by ID.
  • reservation.creator_user_id references an IAM user.
  • employee_service_config.service_id references an item from the Catalog module.
  • staff_id fields reference the Staff module.

Availability rules (blocks + exceptions + the establishment's daily window, crossed as webtyp.com/time DayBounds) are enforced at the service layer, not via cross-module FKs. appointment_booking/go.mod keeps zero veltylabs dependencies — the establishment bound is a port declared here (BoundsReader), satisfied structurally by veltylabs/business_calendar. Reservation status is enforced by an in-code FSM — no reservation_status table.

Development Rules (SKILL)

Core Constraints & Rules
  • FSM-only status changes: Reservation.Status MUST only change via FSM.Transition(current, event) — except entering/leaving CONFLICTED, which a recomputation writes directly and restores via StatusBeforeConflict. Valid events: CONFIRM, CANCEL, COMPLETE, NO_SHOW_EVENT, EXPIRE, RESCHEDULE, CONFLICT, RESOLVE.
  • RESCHEDULED ≠ CANCELLED: When a reservation is replaced by a new one, the original is marked RESCHEDULED (not CANCELLED) for audit trail integrity. These are different terminal states. CONFLICTED is not terminal.
  • Timezone is in WorkCalendarConfig: WorkCalendarBlock and WorkCalendarException have NO timezone field. Always load WorkCalendarConfig first to get the IANA timezone. Block hours are local minutes from midnight (e.g., 540 = 09:00), converted to UTC at query time via LocalIntToUnixUTC.
  • Snapshotting: At reservation creation, price, currency, duration, staffID, and serviceID are snapshotted. Never mutate snapshot fields after creation. StaffIdsnapshot/ServiceIdsnapshot use the historical column names staff_idsnapshot/service_idsnapshot — never rename.
  • A schedule change reports its conflicts: every professional edit (save_day_blocks, save_date_blocks, mark_working_days, unmark_working_days, exceptions) recomputes future reservations in the affected range and marks/clears CONFLICTED. Establishment-wide changes go through RecomputeConflicts. When nobody is affected, nothing is published (CU-19).
  • No RBAC here: This module trusts actorID as an already-authorized string. Authorization is enforced by the gateway before the service. This module only stores actorID as an audit field.
  • Event publishing is fire-and-forget via the injected events.Publisher (Deps.Publisher). nil publisher is safe.
  • No cross-module imports. External dependencies are accessed only via injected interfaces: StaffReader, CatalogReader, DirectoryReader, BoundsReader.
Injected Interfaces (constructor parameters)

The service holds *orm.DB directly — no intermediate store interfaces. Only cross-module dependencies are injected:

type Deps struct {
    Staff     StaffReader     // provided by staff module
    Catalog   CatalogReader   // provided by catalog module
    Directory DirectoryReader // provided by directory module
    IDs       model.IDGenerator // required — never constructed inside the module
    Publisher events.Publisher  // nil = events disabled
    Bounds    BoundsReader      // nil = unbounded (a freelancer without an establishment)
}

func New(db *orm.DB, deps Deps) (*Module, error)
Domain Events Published
Event constant When
appointment.reservation.created After CreateReservation commits
appointment.reservation.rescheduled For the original reservation during reschedule
appointment.reservation.confirmed After CONFIRM transition
appointment.reservation.cancelled After CANCEL transition
appointment.reservation.completed After COMPLETE transition
appointment.reservation.no_show After NO_SHOW transition
appointment.reservation.expired After EXPIRE transition
appointment.schedule.changed Once per staff whose schedule change put ≥1 reservation in conflict (payload ScheduleChangedPayload{TenantId, StaffId, FromDate, ToDate, ConflictCount})
appointment.reservation.conflicted Per conflicted reservation, only when the change came from the professional's own edit
Key Error Sentinels
Error When
ErrSlotTaken Slot not available or concurrent booking race
ErrConflict Optimistic concurrency mismatch on reservation updates
ErrCalendarConfigNotFound Saving blocks before upsert_calendar_config
ErrInvalidBlock start_min not < end_min, or outside 0..1439
ErrBlocksOverlap Two blocks of the same day overlap
ErrBlockOutsideBusinessHours A block falls outside the establishment's opening window
ErrBlockOnClosedDay The establishment is closed on that date
ErrInvalidTransition FSM rejects the event for the current status
Composition Root (how to wire this module)
scheduling, _ := appointmentbooking.New(db, appointmentbooking.Deps{
    Staff:     staffmodule.New(db),        // implements StaffReader
    Catalog:   catalogmodule.New(db),      // implements CatalogReader
    Directory: directorymodule.New(db),    // implements DirectoryReader
    IDs:       idGen,                      // model.IDGenerator
    Publisher: eventBus,                   // nil = events disabled
    Bounds:    businesscalendarModule,     // implements BoundsReader; nil = unbounded
})
scheduling.MountOps(opRegistry)            // transport harvests the ops
reservationsView := scheduling.NewView(caller, tenantId, staffId)

Establishment-wide recomputation is wired by the application (it knows both modules):

broker.Subscribe(businesscalendar.EventCalendarChanged, func(ev events.Event) {
    var p businesscalendar.CalendarChangedPayload
    // decode; opening earlier can never invalidate a booking
    if !p.Closed {
        return
    }
    _, _ = book.RecomputeConflicts(config.TenantID, p.FromDate, p.ToDate)
})
Available Ops (19 total)

create_reservation, get_reservation, list_reservations_by_staff, list_reservations_by_client, change_reservation_status, expire_pending_reservations, list_conflicting_reservations, recompute_conflicts, upsert_calendar_config, save_day_blocks, save_date_blocks, mark_working_days, unmark_working_days, list_blocks, get_day_bounds, add_calendar_exception, remove_calendar_exception, list_availability, list_exceptions

expire_pending_reservations is the only trigger for the EXPIRE FSM event; it must be called by an external scheduler — the module has no internal background process.

list_blocks and list_exceptions are the raw reads a schedule editor needs; the caller-side face is NewScheduleClient (see below).

ScheduleClient — the schedule-editor face

NewScheduleClient(caller router.Caller, tenantId, staffId string) *ScheduleClient is a caller-side typed client over the calendar ops, intended to be adapted by an app to a scheduleeditor UI component. Importing only router + this module's types, it stays renderer-agnostic:

cl := appointmentbooking.NewScheduleClient(caller, "t1", "s1")
cl.Blocks(func(rows []appointmentbooking.WorkCalendarBlock, err error) { /* … */ })
cl.SaveDayBlocks(dayOfWeek, blocks, func(err error) { /* … */ })
cl.Exceptions(from, to, func(rows []appointmentbooking.WorkCalendarException, err error) { /* … */ })
cl.AddException(exc, func(err error) { /* … */ })
cl.RemoveException(exceptionID, func(err error) { /* … */ })

A schedule mutation publishes appointment.schedule.changed (with the affected range and conflict count) only when it actually put reservations in conflict.

Service interface

type SchedulingService interface {
    // Calendar management
    UpsertCalendarConfig(cfg WorkCalendarConfig) error
    SaveDayBlocks(tenantId, staffId string, dayOfWeek int, blocks []WorkCalendarBlock) error
    SaveDateBlocks(tenantId, staffId string, date int64, blocks []WorkCalendarBlock) error
    MarkWorkingDays(tenantId, staffId string, dates []int64, startMin, endMin int) error
    UnmarkWorkingDays(tenantId, staffId string, dates []int64) error
    ListBlocks(tenantId, staffId string) ([]WorkCalendarBlock, error)
    AddException(exc WorkCalendarException) error
    RemoveException(tenantId, exceptionId string) error
    ListExceptions(tenantId, staffId string, from, to int64) ([]WorkCalendarException, error)
    GetDayBounds(date int64) (tinytime.DayBounds, error)

    // Availability
    ListAvailability(tenantId, staffId, configId string, from, to int64) ([]TimeSlot, error)

    // Reservations
    CreateReservation(cmd CreateReservationCmd) (Reservation, error)
    GetReservation(tenantId, id string) (Reservation, error)
    ListReservationsByStaff(tenantId, staffId string, from, to int64) ([]Reservation, error)
    ListReservationsByClient(tenantId, clientId string) ([]Reservation, error)
    ChangeReservationStatus(cmd ChangeStatusCmd) error
    ExpirePendingReservations(tenantId string, before int64) (int, error)

    // Conflicts
    ListConflictingReservations(tenantId, staffId string, from int64) ([]ConflictingReservation, error)
    RecomputeConflicts(tenantId string, from, to int64) (int, error)
}

This interface depends on injected readers:

  • DirectoryReader — validates client existence
  • StaffReader — validates staff existence
  • CatalogReader — validates service existence
  • BoundsReader — answers "which minutes of a date are usable at all" (optional)

Documentation

Index

Constants

View Source
const (
	StatusPending     = "PENDING"
	StatusConfirmed   = "CONFIRMED"
	StatusCancelled   = "CANCELLED"
	StatusCompleted   = "COMPLETED"
	StatusNoShow      = "NO_SHOW"
	StatusExpired     = "EXPIRED"     // reserva no pagada que expiró (disparador: scheduler externo vía MCP)
	StatusRescheduled = "RESCHEDULED" // reserva original reemplazada por una nueva (registro de auditoría)
	StatusConflicted  = "CONFLICTED"  // la agenda actual ya no cubre esta reserva — NO es terminal
)

Estados

View Source
const (
	EventConfirm    = "CONFIRM"
	EventCancel     = "CANCEL"
	EventComplete   = "COMPLETE"
	EventNoShow     = "NO_SHOW_EVENT"
	EventExpire     = "EXPIRE"
	EventReschedule = "RESCHEDULE" // marca la original como RESCHEDULED; la nueva reserva se crea atómicamente
	EventConflict   = "CONFLICT"   // una recomputación pone la reserva en conflicto
	EventResolve    = "RESOLVE"    // una recomputación la saca del conflicto
)

Eventos

View Source
const (
	OpCreateReservation           = "create_reservation"
	OpGetReservation              = "get_reservation"
	OpListReservationsByStaff     = "list_reservations_by_staff"
	OpListReservationsByClient    = "list_reservations_by_client"
	OpChangeReservationStatus     = "change_reservation_status"
	OpExpirePendingReservations   = "expire_pending_reservations"
	OpUpsertCalendarConfig        = "upsert_calendar_config"
	OpSaveDayBlocks               = "save_day_blocks"
	OpSaveDateBlocks              = "save_date_blocks"
	OpMarkWorkingDays             = "mark_working_days"
	OpUnmarkWorkingDays           = "unmark_working_days"
	OpListBlocks                  = "list_blocks"
	OpGetDayBounds                = "get_day_bounds"
	OpAddCalendarException        = "add_calendar_exception"
	OpRemoveCalendarException     = "remove_calendar_exception"
	OpListAvailability            = "list_availability"
	OpListExceptions              = "list_exceptions"
	OpListConflictingReservations = "list_conflicting_reservations"
	OpRecomputeConflicts          = "recompute_conflicts"
)
View Source
const (
	ExcHoliday      = "HOLIDAY"
	ExcSpecialHours = "SPECIAL_HOURS"
	ExcBlocked      = "BLOCKED"
)

Tipos de excepción de calendario (valor de WorkCalendarException.ExceptionType).

View Source
const (
	EventReservationCreated     = "appointment.reservation.created"
	EventReservationConfirmed   = "appointment.reservation.confirmed"
	EventReservationCancelled   = "appointment.reservation.cancelled"
	EventReservationCompleted   = "appointment.reservation.completed"
	EventReservationNoShow      = "appointment.reservation.no_show"
	EventReservationExpired     = "appointment.reservation.expired"
	EventReservationRescheduled = "appointment.reservation.rescheduled"
	// EventReservationConflicted se emite UNA VEZ POR reserva cuando un cambio
	// vino de la edición del propio profesional (§8.2) — el notificador llega al
	// paciente sin sondeo. El caso establishment-wide (feriado/cierre que golpea
	// a decenas de profesionales) publica SOLO el summary por staff y el
	// consumidor lee ListConflictingReservations (§8.6).
	EventReservationConflicted = "appointment.reservation.conflicted"
	// EventScheduleChanged se emite al mutar la agenda de un profesional o
	// recomputar conflictos tras un cambio del establecimiento. Un consumidor lo
	// usa para recalcular disponibilidad / notificar (p. ej. reservation recarga
	// sus huecos libres). Solo se emite cuando el cambio PUSO reservas en
	// conflicto (CU-19: sin afectados ⇒ silencio).
	EventScheduleChanged = "appointment.schedule.changed"
)

Eventos de dominio emitidos por este módulo.

View Source
const (
	ConflictReasonOutsideBlocks        = "OUTSIDE_BLOCKS"
	ConflictReasonDayClosed            = "DAY_CLOSED"
	ConflictReasonOutsideBusinessHours = "OUTSIDE_BUSINESS_HOURS"
)

Motivos de ConflictingReservation.Reason — el vocabulario NEUTRO del módulo. Concretamente NO arrastra la razón del establecimiento (por qué un día está cerrado): time.DayBounds lo omite deliberadamente y este módulo lo respeta.

View Source
const ConflictHorizonDays = 370

ConflictHorizonDays es el forward horizon del módulo: cuando no hay rango que acote (un cambio semanal, o to == 0), los conflictos se evalúan hasta aquí.

Variables

View Source
var (
	ErrNotFound = fmt.Err("record", "not", "found")
	ErrConflict = fmt.Err("optimistic", "concurrency", "conflict")
)

Errores sentinela a nivel de paquete

View Source
var (
	ErrCalendarConfigNotFound    = fmt.Err("calendar", "config", "not", "found")
	ErrSlotTaken                 = fmt.Err("slot", "taken")
	ErrInvalidBlock              = fmt.Err("appointment_booking: start_min must be < end_min and both within 0..1439")
	ErrBlocksOverlap             = fmt.Err("appointment_booking: two blocks of the same day overlap")
	ErrBlockOutsideBusinessHours = fmt.Err("appointment_booking: block falls outside the establishment's opening hours")
	ErrBlockOnClosedDay          = fmt.Err("appointment_booking: the establishment is closed on that date")
)
View Source
var AddCalendarExceptionArgsModel = model.Definition{
	Name: "add_calendar_exception_args",
	Fields: model.Fields{
		{Name: "tenant_id", Type: model.Text()},
		{Name: "staff_id", Type: input.Text()},
		{Name: "specific_date", Type: input.Number()},
		{Name: "exception_type", Type: input.Text()},
		{Name: "start_time", Type: input.Number()},
		{Name: "end_time", Type: input.Number()},
		{Name: "notes", Type: input.Text()},
	},
}
View Source
var ChangeReservationStatusArgsModel = model.Definition{
	Name: "change_reservation_status_args",
	Fields: model.Fields{
		{Name: "tenant_id", Type: model.Text()},
		{Name: "id", Type: input.Text()},
		{Name: "event", Type: input.Text()},
		{Name: "actor_id", Type: input.Text()},
		{Name: "payment_id", Type: input.Text()},
		{Name: "revision", Type: input.Number()},
	},
}
View Source
var ConflictingReservationModel = model.Definition{
	Name: "conflicting_reservation",
	Fields: model.Fields{
		{Name: "reservation_id", Type: model.Text()},
		{Name: "starts_at", Type: model.Int()},
		{Name: "client_id", Type: model.Text()},
		{Name: "reason", Type: model.Text()},
	},
}

ConflictingReservationModel es transport-only (salida de list_conflicting_reservations / recompute_conflicts) — nunca se renderiza como form editable.

View Source
var CreateReservationArgsModel = model.Definition{
	Name: "create_reservation_args",
	Fields: model.Fields{
		{Name: "tenant_id", Type: model.Text()},
		{Name: "client_id", Type: input.Text()},
		{Name: "creator_user_id", Type: input.Text()},
		{Name: "employee_service_config_id", Type: input.Text()},
		{Name: "slot_start_utc", Type: input.Number()},
		{Name: "notes", Type: input.Text()},
		{Name: "rescheduled_from_id", Type: input.Text()},
	},
}
View Source
var DayBoundsResultModel = model.Definition{
	Name: "day_bounds_result",
	Fields: model.Fields{
		{Name: "open", Type: model.Bool()},
		{Name: "open_min", Type: model.Int()},
		{Name: "close_min", Type: model.Int()},
	},
}

DayBoundsResultModel es transport-only (salida de get_day_bounds) — la proyección encodable de time.DayBounds para que el editor acote sus controles (§6.2). time.DayBounds NO es model.Encodable, así que se cruza por esta forma.

View Source
var EmployeeServiceConfigModel = model.Definition{
	Name: "employee_service_config",
	Fields: model.Fields{
		{Name: "id", Type: model.Text(), DB: &model.FieldDB{PK: true}},
		{Name: "tenant_id", Type: model.Text(), NotNull: true},
		{Name: "staff_id", Type: model.Text(), NotNull: true},
		{Name: "service_id", Type: model.Text(), NotNull: true},
		{Name: "duration_min", Type: model.Int()},
		{Name: "buffer_min", Type: model.Int()},
		{Name: "price_override", Type: model.Float()},
		{Name: "payment_required", Type: model.Bool()},
		{Name: "is_active", Type: model.Bool()},
	},
}
View Source
var EmployeeServiceConfig_ = struct {
	Id              string
	TenantId        string
	StaffId         string
	ServiceId       string
	DurationMin     string
	BufferMin       string
	PriceOverride   string
	PaymentRequired string
	IsActive        string
}{
	Id:              "id",
	TenantId:        "tenant_id",
	StaffId:         "staff_id",
	ServiceId:       "service_id",
	DurationMin:     "duration_min",
	BufferMin:       "buffer_min",
	PriceOverride:   "price_override",
	PaymentRequired: "payment_required",
	IsActive:        "is_active",
}
View Source
var ErrInvalidTransition = fmt.Err("invalid", "transition")

ErrInvalidTransition se devuelve cuando una transición no está permitida.

View Source
var ExpirePendingReservationsArgsModel = model.Definition{
	Name: "expire_pending_reservations_args",
	Fields: model.Fields{
		{Name: "tenant_id", Type: model.Text()},
		{Name: "before", Type: input.Number()},
	},
}
View Source
var GetDayBoundsArgsModel = model.Definition{
	Name: "get_day_bounds_args",
	Fields: model.Fields{
		{Name: "tenant_id", Type: model.Text()},
		{Name: "date", Type: input.Number()},
	},
}
View Source
var GetReservationArgsModel = model.Definition{
	Name: "get_reservation_args",
	Fields: model.Fields{
		{Name: "tenant_id", Type: model.Text()},
		{Name: "id", Type: input.Text()},
	},
}
View Source
var ListAvailabilityArgsModel = model.Definition{
	Name: "list_availability_args",
	Fields: model.Fields{
		{Name: "tenant_id", Type: model.Text()},
		{Name: "staff_id", Type: input.Text()},
		{Name: "config_id", Type: input.Text()},
		{Name: "from", Type: input.Number()},
		{Name: "to", Type: input.Number()},
	},
}
View Source
var ListBlocksArgsModel = model.Definition{
	Name: "list_blocks_args",
	Fields: model.Fields{
		{Name: "tenant_id", Type: model.Text()},
		{Name: "staff_id", Type: input.Text()},
	},
}
View Source
var ListConflictingReservationsArgsModel = model.Definition{
	Name: "list_conflicting_reservations_args",
	Fields: model.Fields{
		{Name: "tenant_id", Type: model.Text()},
		{Name: "staff_id", Type: input.Text()},
		{Name: "from", Type: input.Number()},
	},
}
View Source
var ListExceptionsArgsModel = model.Definition{
	Name: "list_exceptions_args",
	Fields: model.Fields{
		{Name: "tenant_id", Type: model.Text()},
		{Name: "staff_id", Type: input.Text()},
		{Name: "from", Type: input.Number()},
		{Name: "to", Type: input.Number()},
	},
}
View Source
var ListReservationsByClientArgsModel = model.Definition{
	Name: "list_reservations_by_client_args",
	Fields: model.Fields{
		{Name: "tenant_id", Type: model.Text()},
		{Name: "client_id", Type: input.Text()},
	},
}
View Source
var ListReservationsByStaffArgsModel = model.Definition{
	Name: "list_reservations_by_staff_args",
	Fields: model.Fields{
		{Name: "tenant_id", Type: model.Text()},
		{Name: "staff_id", Type: input.Text()},
		{Name: "from", Type: input.Number()},
		{Name: "to", Type: input.Number()},
	},
}
View Source
var MarkWorkingDaysArgsModel = model.Definition{
	Name: "mark_working_days_args",
	Fields: model.Fields{
		{Name: "tenant_id", Type: model.Text()},
		{Name: "staff_id", Type: input.Text()},
		{Name: "dates", Type: model.IntSlice()},
		{Name: "start_min", Type: input.Number()},
		{Name: "end_min", Type: input.Number()},
	},
}
View Source
var RecomputeConflictsArgsModel = model.Definition{
	Name: "recompute_conflicts_args",
	Fields: model.Fields{
		{Name: "tenant_id", Type: model.Text()},
		{Name: "from", Type: input.Number()},
		{Name: "to", Type: input.Number()},
	},
}
View Source
var RemoveCalendarExceptionArgsModel = model.Definition{
	Name: "remove_calendar_exception_args",
	Fields: model.Fields{
		{Name: "tenant_id", Type: model.Text()},
		{Name: "exception_id", Type: input.Text()},
	},
}
View Source
var ReservationModel = model.Definition{
	Name: "reservation",
	Fields: model.Fields{
		{Name: "id", Type: model.Text(), DB: &model.FieldDB{PK: true}},
		{Name: "tenant_id", Type: model.Text(), NotNull: true},
		{Name: "client_id", Type: model.Text(), NotNull: true},
		{Name: "creator_user_id", Type: model.Text()},
		{Name: "employee_service_config_id", Type: model.Text(), NotNull: true},
		{Name: "staff_idsnapshot", Type: model.Text()},
		{Name: "service_idsnapshot", Type: model.Text()},
		{Name: "duration_min_snapshot", Type: model.Int()},
		{Name: "price_snapshot", Type: model.Float()},
		{Name: "currency_snapshot", Type: model.Text()},
		{Name: "reservation_date", Type: model.Int()},
		{Name: "reservation_time", Type: model.Int()},
		{Name: "local_string_date", Type: model.Text()},
		{Name: "local_string_time", Type: model.Text()},

		{Name: "status", Type: model.Text(), NotNull: true},
		{Name: "rescheduled_from_id", Type: model.Text()},

		{Name: "status_before_conflict", Type: model.Text()},
		{Name: "payment_id", Type: model.Text()},
		{Name: "notes", Type: model.Text()},
		{Name: "updated_at", Type: model.Int()},
		{Name: "updated_by", Type: model.Text()},
		{Name: "revision", Type: model.Int()},
	},
}

NOTA: "staff_idsnapshot" / "service_idsnapshot" preservan EXACTAMENTE el nombre de columna actual (irregularidad histórica, sin guión bajo) — NO renombrar la columna, la tabla ya existe con ese nombre en producción.

View Source
var Reservation_ = struct {
	Id                      string
	TenantId                string
	ClientId                string
	CreatorUserId           string
	EmployeeServiceConfigId string
	StaffIdsnapshot         string
	ServiceIdsnapshot       string
	DurationMinSnapshot     string
	PriceSnapshot           string
	CurrencySnapshot        string
	ReservationDate         string
	ReservationTime         string
	LocalStringDate         string
	LocalStringTime         string
	Status                  string
	RescheduledFromId       string
	StatusBeforeConflict    string
	PaymentId               string
	Notes                   string
	UpdatedAt               string
	UpdatedBy               string
	Revision                string
}{
	Id:                      "id",
	TenantId:                "tenant_id",
	ClientId:                "client_id",
	CreatorUserId:           "creator_user_id",
	EmployeeServiceConfigId: "employee_service_config_id",
	StaffIdsnapshot:         "staff_idsnapshot",
	ServiceIdsnapshot:       "service_idsnapshot",
	DurationMinSnapshot:     "duration_min_snapshot",
	PriceSnapshot:           "price_snapshot",
	CurrencySnapshot:        "currency_snapshot",
	ReservationDate:         "reservation_date",
	ReservationTime:         "reservation_time",
	LocalStringDate:         "local_string_date",
	LocalStringTime:         "local_string_time",
	Status:                  "status",
	RescheduledFromId:       "rescheduled_from_id",
	StatusBeforeConflict:    "status_before_conflict",
	PaymentId:               "payment_id",
	Notes:                   "notes",
	UpdatedAt:               "updated_at",
	UpdatedBy:               "updated_by",
	Revision:                "revision",
}
View Source
var SaveDateBlocksArgsModel = model.Definition{
	Name: "save_date_blocks_args",
	Fields: model.Fields{
		{Name: "tenant_id", Type: model.Text()},
		{Name: "staff_id", Type: input.Text()},
		{Name: "specific_date", Type: input.Number()},
		{Name: "blocks", Type: model.StructSlice(&WorkCalendarBlockModel)},
	},
}
View Source
var SaveDayBlocksArgsModel = model.Definition{
	Name: "save_day_blocks_args",
	Fields: model.Fields{
		{Name: "tenant_id", Type: model.Text()},
		{Name: "staff_id", Type: input.Text()},
		{Name: "day_of_week", Type: input.Number()},
		{Name: "blocks", Type: model.StructSlice(&WorkCalendarBlockModel)},
	},
}
View Source
var TimeSlotModel = model.Definition{
	Name: "time_slot",
	Fields: model.Fields{
		{Name: "start_utc", Type: model.Int()},
		{Name: "end_utc", Type: model.Int()},
	},
}
View Source
var UnmarkWorkingDaysArgsModel = model.Definition{
	Name: "unmark_working_days_args",
	Fields: model.Fields{
		{Name: "tenant_id", Type: model.Text()},
		{Name: "staff_id", Type: input.Text()},
		{Name: "dates", Type: model.IntSlice()},
	},
}
View Source
var UpsertCalendarConfigArgsModel = model.Definition{
	Name: "upsert_calendar_config_args",
	Fields: model.Fields{
		{Name: "tenant_id", Type: model.Text()},
		{Name: "staff_id", Type: input.Text()},
		{Name: "timezone", Type: input.Text()},
		{Name: "is_active", Type: input.Checkbox()},
	},
}
View Source
var WorkCalendarBlockModel = model.Definition{
	Name: "work_calendar_block",
	Fields: model.Fields{
		{Name: "id", Type: model.Text(), DB: &model.FieldDB{PK: true}},
		{Name: "tenant_id", Type: model.Text(), NotNull: true},
		{Name: "staff_id", Type: model.Text(), NotNull: true},
		{Name: "day_of_week", Type: model.Int(), NotNull: true},
		{Name: "specific_date", Type: model.Int(), NotNull: true},
		{Name: "start_min", Type: model.Int(), NotNull: true},
		{Name: "end_min", Type: model.Int(), NotNull: true},
		{Name: "is_active", Type: model.Bool(), NotNull: true},
	},
}

WorkCalendarBlockModel: one row per block of working time. A day may hold several — "morning 09:00–13:00, afternoon 15:00–19:00" is two rows, and the lunch break is the GAP between them. There is deliberately no break field: a break that is a column can only ever describe one interruption, and the gap describes any number.

specific_date == 0 → the block is WEEKLY and applies to day_of_week. specific_date > 0 → the block is DATED and applies to that date only,

and day_of_week carries no meaning.

A dated block OPENS its day whether or not a weekly block covers that weekday. That is what lets an irregular professional mark the days they work with no weekly template at all.

View Source
var WorkCalendarBlock_ = struct {
	Id           string
	TenantId     string
	StaffId      string
	DayOfWeek    string
	SpecificDate string
	StartMin     string
	EndMin       string
	IsActive     string
}{
	Id:           "id",
	TenantId:     "tenant_id",
	StaffId:      "staff_id",
	DayOfWeek:    "day_of_week",
	SpecificDate: "specific_date",
	StartMin:     "start_min",
	EndMin:       "end_min",
	IsActive:     "is_active",
}
View Source
var WorkCalendarConfigModel = model.Definition{
	Name: "work_calendar_config",
	Fields: model.Fields{
		{Name: "id", Type: model.Text(), DB: &model.FieldDB{PK: true}},
		{Name: "tenant_id", Type: model.Text(), NotNull: true},
		{Name: "staff_id", Type: model.Text(), NotNull: true},
		{Name: "timezone", Type: model.Text(), NotNull: true},
		{Name: "is_active", Type: model.Bool()},
	},
}
View Source
var WorkCalendarConfig_ = struct {
	Id       string
	TenantId string
	StaffId  string
	Timezone string
	IsActive string
}{
	Id:       "id",
	TenantId: "tenant_id",
	StaffId:  "staff_id",
	Timezone: "timezone",
	IsActive: "is_active",
}
View Source
var WorkCalendarExceptionModel = model.Definition{
	Name: "work_calendar_exception",
	Fields: model.Fields{
		{Name: "id", Type: model.Text(), DB: &model.FieldDB{PK: true}},
		{Name: "tenant_id", Type: model.Text(), NotNull: true},
		{Name: "staff_id", Type: model.Text(), NotNull: true},
		{Name: "specific_date", Type: model.Int()},
		{Name: "exception_type", Type: model.Text()},
		{Name: "start_time", Type: model.Int()},
		{Name: "end_time", Type: model.Int()},
		{Name: "notes", Type: model.Text()},
	},
}
View Source
var WorkCalendarException_ = struct {
	Id            string
	TenantId      string
	StaffId       string
	SpecificDate  string
	ExceptionType string
	StartTime     string
	EndTime       string
	Notes         string
}{
	Id:            "id",
	TenantId:      "tenant_id",
	StaffId:       "staff_id",
	SpecificDate:  "specific_date",
	ExceptionType: "exception_type",
	StartTime:     "start_time",
	EndTime:       "end_time",
	Notes:         "notes",
}

Functions

func IsTerminal

func IsTerminal(status string) bool

IsTerminal devuelve true si el estado no tiene transiciones salientes.

func LocalIntToUnixUTC

func LocalIntToUnixUTC(date int64, localInt int, tz string) int64

LocalIntToUnixUTC interpreta localInt como minutos desde la medianoche en la fecha dada (medianoche UTC) en la zona horaria (tz) especificada.

func NewView

func NewView(caller router.Caller, tenantId, staffId string) view.Presenter

NewView construye el Presenter de Reservation — acotado al horario de un solo staff, ya que no existe una operación "listar todas las reservas de un tenant" sin acotar (ver docs/ARCHITECTURE.md §7). Solo lista: sin capacidad Saver/Deleter (las reservas solo mutan vía las transiciones FSM-guardadas de ChangeReservationStatus, y nunca se eliminan físicamente).

func Transition

func Transition(current, event string) (string, error)

Transition devuelve el siguiente estado, o un error si la transición no es válida.

Types

type AddCalendarExceptionArgs

type AddCalendarExceptionArgs struct {
	TenantId      string
	StaffId       string
	SpecificDate  int64
	ExceptionType string
	StartTime     int64
	EndTime       int64
	Notes         string
}

func (*AddCalendarExceptionArgs) DecodeFields

func (m *AddCalendarExceptionArgs) DecodeFields(r model.FieldReader)

func (*AddCalendarExceptionArgs) EncodeFields

func (m *AddCalendarExceptionArgs) EncodeFields(w model.FieldWriter)

func (*AddCalendarExceptionArgs) IsNil

func (m *AddCalendarExceptionArgs) IsNil() bool

func (*AddCalendarExceptionArgs) ModelName

func (m *AddCalendarExceptionArgs) ModelName() string

func (*AddCalendarExceptionArgs) Pointers

func (m *AddCalendarExceptionArgs) Pointers() []any

func (*AddCalendarExceptionArgs) Schema

func (m *AddCalendarExceptionArgs) Schema() []model.Field

func (*AddCalendarExceptionArgs) Validate

func (m *AddCalendarExceptionArgs) Validate(action byte) error

type AddCalendarExceptionArgsList

type AddCalendarExceptionArgsList []*AddCalendarExceptionArgs

func (*AddCalendarExceptionArgsList) Append

func (*AddCalendarExceptionArgsList) At

func (*AddCalendarExceptionArgsList) DecodeFields

func (s *AddCalendarExceptionArgsList) DecodeFields(_ model.FieldReader)

func (*AddCalendarExceptionArgsList) EncodeFields

func (s *AddCalendarExceptionArgsList) EncodeFields(_ model.FieldWriter)

func (*AddCalendarExceptionArgsList) IsNil

func (*AddCalendarExceptionArgsList) Len

func (*AddCalendarExceptionArgsList) Pointers

func (s *AddCalendarExceptionArgsList) Pointers() []any

func (*AddCalendarExceptionArgsList) Schema

type BoundsReader added in v0.1.5

type BoundsReader interface {
	GetDayBounds(date int64) (tinytime.DayBounds, error)
}

BoundsReader answers "which minutes of this date are usable at all".

Declared here, not imported: a booking module must not depend on any particular institutional calendar. Anything that can answer the question satisfies it — veltylabs/business_calendar does, and so would a static config or a different organisation's calendar.

date is midnight UTC in seconds.

type CatalogReader

type CatalogReader interface {
	ServiceExists(tenantId, serviceId string) (bool, error)
}

CatalogReader verifica que un servicio existe y pertenece al tenant.

type ChangeReservationStatusArgs

type ChangeReservationStatusArgs struct {
	TenantId  string
	Id        string
	Event     string
	ActorId   string
	PaymentId string
	Revision  int64
}

func (*ChangeReservationStatusArgs) DecodeFields

func (m *ChangeReservationStatusArgs) DecodeFields(r model.FieldReader)

func (*ChangeReservationStatusArgs) EncodeFields

func (m *ChangeReservationStatusArgs) EncodeFields(w model.FieldWriter)

func (*ChangeReservationStatusArgs) IsNil

func (m *ChangeReservationStatusArgs) IsNil() bool

func (*ChangeReservationStatusArgs) ModelName

func (m *ChangeReservationStatusArgs) ModelName() string

func (*ChangeReservationStatusArgs) Pointers

func (m *ChangeReservationStatusArgs) Pointers() []any

func (*ChangeReservationStatusArgs) Schema

func (m *ChangeReservationStatusArgs) Schema() []model.Field

func (*ChangeReservationStatusArgs) Validate

func (m *ChangeReservationStatusArgs) Validate(action byte) error

type ChangeReservationStatusArgsList

type ChangeReservationStatusArgsList []*ChangeReservationStatusArgs

func (*ChangeReservationStatusArgsList) Append

func (*ChangeReservationStatusArgsList) At

func (*ChangeReservationStatusArgsList) DecodeFields

func (*ChangeReservationStatusArgsList) EncodeFields

func (*ChangeReservationStatusArgsList) IsNil

func (*ChangeReservationStatusArgsList) Len

func (*ChangeReservationStatusArgsList) Pointers

func (s *ChangeReservationStatusArgsList) Pointers() []any

func (*ChangeReservationStatusArgsList) Schema

type ChangeStatusCmd

type ChangeStatusCmd struct {
	TenantId  string
	Id        string
	Event     string
	ActorId   string
	PaymentId string
	Revision  int
}

type ConflictingReservation added in v0.1.5

type ConflictingReservation struct {
	ReservationId string
	StartsAt      int64
	ClientId      string
	Reason        string
}

func (*ConflictingReservation) DecodeFields added in v0.1.5

func (m *ConflictingReservation) DecodeFields(r model.FieldReader)

func (*ConflictingReservation) EncodeFields added in v0.1.5

func (m *ConflictingReservation) EncodeFields(w model.FieldWriter)

func (*ConflictingReservation) IsNil added in v0.1.5

func (m *ConflictingReservation) IsNil() bool

func (*ConflictingReservation) ModelName added in v0.1.5

func (m *ConflictingReservation) ModelName() string

func (*ConflictingReservation) Pointers added in v0.1.5

func (m *ConflictingReservation) Pointers() []any

func (*ConflictingReservation) Schema added in v0.1.5

func (m *ConflictingReservation) Schema() []model.Field

func (*ConflictingReservation) Validate added in v0.1.5

func (m *ConflictingReservation) Validate(action byte) error

type ConflictingReservationList added in v0.1.5

type ConflictingReservationList []*ConflictingReservation

func (*ConflictingReservationList) Append added in v0.1.5

func (*ConflictingReservationList) At added in v0.1.5

func (*ConflictingReservationList) DecodeFields added in v0.1.5

func (s *ConflictingReservationList) DecodeFields(_ model.FieldReader)

func (*ConflictingReservationList) EncodeFields added in v0.1.5

func (s *ConflictingReservationList) EncodeFields(_ model.FieldWriter)

func (*ConflictingReservationList) IsNil added in v0.1.5

func (s *ConflictingReservationList) IsNil() bool

func (*ConflictingReservationList) Len added in v0.1.5

func (*ConflictingReservationList) Pointers added in v0.1.5

func (s *ConflictingReservationList) Pointers() []any

func (*ConflictingReservationList) Schema added in v0.1.5

func (s *ConflictingReservationList) Schema() []model.Field

type CreateReservationArgs

type CreateReservationArgs struct {
	TenantId                string
	ClientId                string
	CreatorUserId           string
	EmployeeServiceConfigId string
	SlotStartUtc            int64
	Notes                   string
	RescheduledFromId       string
}

func (*CreateReservationArgs) DecodeFields

func (m *CreateReservationArgs) DecodeFields(r model.FieldReader)

func (*CreateReservationArgs) EncodeFields

func (m *CreateReservationArgs) EncodeFields(w model.FieldWriter)

func (*CreateReservationArgs) IsNil

func (m *CreateReservationArgs) IsNil() bool

func (*CreateReservationArgs) ModelName

func (m *CreateReservationArgs) ModelName() string

func (*CreateReservationArgs) Pointers

func (m *CreateReservationArgs) Pointers() []any

func (*CreateReservationArgs) Schema

func (m *CreateReservationArgs) Schema() []model.Field

func (*CreateReservationArgs) Validate

func (m *CreateReservationArgs) Validate(action byte) error

type CreateReservationArgsList

type CreateReservationArgsList []*CreateReservationArgs

func (*CreateReservationArgsList) Append

func (*CreateReservationArgsList) At

func (*CreateReservationArgsList) DecodeFields

func (s *CreateReservationArgsList) DecodeFields(_ model.FieldReader)

func (*CreateReservationArgsList) EncodeFields

func (s *CreateReservationArgsList) EncodeFields(_ model.FieldWriter)

func (*CreateReservationArgsList) IsNil

func (s *CreateReservationArgsList) IsNil() bool

func (*CreateReservationArgsList) Len

func (s *CreateReservationArgsList) Len() int

func (*CreateReservationArgsList) Pointers

func (s *CreateReservationArgsList) Pointers() []any

func (*CreateReservationArgsList) Schema

func (s *CreateReservationArgsList) Schema() []model.Field

type CreateReservationCmd

type CreateReservationCmd struct {
	TenantId                string
	ClientId                string
	CreatorUserId           string
	EmployeeServiceConfigId string
	SlotStartUtc            int64
	Notes                   string
	RescheduledFromId       string
}

type DayBoundsResult added in v0.1.5

type DayBoundsResult struct {
	Open     bool
	OpenMin  int64
	CloseMin int64
}

func (*DayBoundsResult) DecodeFields added in v0.1.5

func (m *DayBoundsResult) DecodeFields(r model.FieldReader)

func (*DayBoundsResult) EncodeFields added in v0.1.5

func (m *DayBoundsResult) EncodeFields(w model.FieldWriter)

func (*DayBoundsResult) IsNil added in v0.1.5

func (m *DayBoundsResult) IsNil() bool

func (*DayBoundsResult) ModelName added in v0.1.5

func (m *DayBoundsResult) ModelName() string

func (*DayBoundsResult) Pointers added in v0.1.5

func (m *DayBoundsResult) Pointers() []any

func (*DayBoundsResult) Schema added in v0.1.5

func (m *DayBoundsResult) Schema() []model.Field

func (*DayBoundsResult) Validate added in v0.1.5

func (m *DayBoundsResult) Validate(action byte) error

type DayBoundsResultList added in v0.1.5

type DayBoundsResultList []*DayBoundsResult

func (*DayBoundsResultList) Append added in v0.1.5

func (s *DayBoundsResultList) Append() model.Fielder

func (*DayBoundsResultList) At added in v0.1.5

func (*DayBoundsResultList) DecodeFields added in v0.1.5

func (s *DayBoundsResultList) DecodeFields(_ model.FieldReader)

func (*DayBoundsResultList) EncodeFields added in v0.1.5

func (s *DayBoundsResultList) EncodeFields(_ model.FieldWriter)

func (*DayBoundsResultList) IsNil added in v0.1.5

func (s *DayBoundsResultList) IsNil() bool

func (*DayBoundsResultList) Len added in v0.1.5

func (s *DayBoundsResultList) Len() int

func (*DayBoundsResultList) Pointers added in v0.1.5

func (s *DayBoundsResultList) Pointers() []any

func (*DayBoundsResultList) Schema added in v0.1.5

func (s *DayBoundsResultList) Schema() []model.Field

type Deps

type Deps struct {
	Staff     StaffReader
	Catalog   CatalogReader
	Directory DirectoryReader
	IDs       model.IDGenerator // requerido
	Publisher events.Publisher  // opcional — nil desactiva
	// Bounds constrains every block to the institution's usable window.
	// OPTIONAL: nil means unbounded, which is correct for an app with no
	// institution above the professional (a freelancer's booking page).
	Bounds BoundsReader
}

type DirectoryReader

type DirectoryReader interface {
	ClientExists(tenantId, clientId string) (bool, error)
}

DirectoryReader verifica que un cliente existe y pertenece al tenant.

type EmployeeServiceConfig

type EmployeeServiceConfig struct {
	Id              string
	TenantId        string
	StaffId         string
	ServiceId       string
	DurationMin     int64
	BufferMin       int64
	PriceOverride   float64
	PaymentRequired bool
	IsActive        bool
}

func ReadOneEmployeeServiceConfig

func ReadOneEmployeeServiceConfig(qb *orm.QB, model *EmployeeServiceConfig) (*EmployeeServiceConfig, error)

func (*EmployeeServiceConfig) DecodeFields

func (m *EmployeeServiceConfig) DecodeFields(r model.FieldReader)

func (*EmployeeServiceConfig) EncodeFields

func (m *EmployeeServiceConfig) EncodeFields(w model.FieldWriter)

func (*EmployeeServiceConfig) IsNil

func (m *EmployeeServiceConfig) IsNil() bool

func (*EmployeeServiceConfig) ModelName

func (m *EmployeeServiceConfig) ModelName() string

func (*EmployeeServiceConfig) Pointers

func (m *EmployeeServiceConfig) Pointers() []any

func (*EmployeeServiceConfig) Schema

func (m *EmployeeServiceConfig) Schema() []model.Field

func (*EmployeeServiceConfig) Validate

func (m *EmployeeServiceConfig) Validate(action byte) error

type EmployeeServiceConfigList

type EmployeeServiceConfigList []*EmployeeServiceConfig

func ReadAllEmployeeServiceConfig

func ReadAllEmployeeServiceConfig(qb *orm.QB) (EmployeeServiceConfigList, error)

func (*EmployeeServiceConfigList) Append

func (*EmployeeServiceConfigList) At

func (*EmployeeServiceConfigList) DecodeFields

func (s *EmployeeServiceConfigList) DecodeFields(_ model.FieldReader)

func (*EmployeeServiceConfigList) EncodeFields

func (s *EmployeeServiceConfigList) EncodeFields(_ model.FieldWriter)

func (*EmployeeServiceConfigList) IsNil

func (s *EmployeeServiceConfigList) IsNil() bool

func (*EmployeeServiceConfigList) Len

func (s *EmployeeServiceConfigList) Len() int

func (*EmployeeServiceConfigList) Pointers

func (s *EmployeeServiceConfigList) Pointers() []any

func (*EmployeeServiceConfigList) Schema

func (s *EmployeeServiceConfigList) Schema() []model.Field

type ExpirePendingReservationsArgs

type ExpirePendingReservationsArgs struct {
	TenantId string
	Before   int64
}

func (*ExpirePendingReservationsArgs) DecodeFields

func (m *ExpirePendingReservationsArgs) DecodeFields(r model.FieldReader)

func (*ExpirePendingReservationsArgs) EncodeFields

func (m *ExpirePendingReservationsArgs) EncodeFields(w model.FieldWriter)

func (*ExpirePendingReservationsArgs) IsNil

func (*ExpirePendingReservationsArgs) ModelName

func (m *ExpirePendingReservationsArgs) ModelName() string

func (*ExpirePendingReservationsArgs) Pointers

func (m *ExpirePendingReservationsArgs) Pointers() []any

func (*ExpirePendingReservationsArgs) Schema

func (*ExpirePendingReservationsArgs) Validate

func (m *ExpirePendingReservationsArgs) Validate(action byte) error

type ExpirePendingReservationsArgsList

type ExpirePendingReservationsArgsList []*ExpirePendingReservationsArgs

func (*ExpirePendingReservationsArgsList) Append

func (*ExpirePendingReservationsArgsList) At

func (*ExpirePendingReservationsArgsList) DecodeFields

func (*ExpirePendingReservationsArgsList) EncodeFields

func (*ExpirePendingReservationsArgsList) IsNil

func (*ExpirePendingReservationsArgsList) Len

func (*ExpirePendingReservationsArgsList) Pointers

func (s *ExpirePendingReservationsArgsList) Pointers() []any

func (*ExpirePendingReservationsArgsList) Schema

type GetDayBoundsArgs added in v0.1.5

type GetDayBoundsArgs struct {
	TenantId string
	Date     int64
}

func (*GetDayBoundsArgs) DecodeFields added in v0.1.5

func (m *GetDayBoundsArgs) DecodeFields(r model.FieldReader)

func (*GetDayBoundsArgs) EncodeFields added in v0.1.5

func (m *GetDayBoundsArgs) EncodeFields(w model.FieldWriter)

func (*GetDayBoundsArgs) IsNil added in v0.1.5

func (m *GetDayBoundsArgs) IsNil() bool

func (*GetDayBoundsArgs) ModelName added in v0.1.5

func (m *GetDayBoundsArgs) ModelName() string

func (*GetDayBoundsArgs) Pointers added in v0.1.5

func (m *GetDayBoundsArgs) Pointers() []any

func (*GetDayBoundsArgs) Schema added in v0.1.5

func (m *GetDayBoundsArgs) Schema() []model.Field

func (*GetDayBoundsArgs) Validate added in v0.1.5

func (m *GetDayBoundsArgs) Validate(action byte) error

type GetDayBoundsArgsList added in v0.1.5

type GetDayBoundsArgsList []*GetDayBoundsArgs

func (*GetDayBoundsArgsList) Append added in v0.1.5

func (s *GetDayBoundsArgsList) Append() model.Fielder

func (*GetDayBoundsArgsList) At added in v0.1.5

func (*GetDayBoundsArgsList) DecodeFields added in v0.1.5

func (s *GetDayBoundsArgsList) DecodeFields(_ model.FieldReader)

func (*GetDayBoundsArgsList) EncodeFields added in v0.1.5

func (s *GetDayBoundsArgsList) EncodeFields(_ model.FieldWriter)

func (*GetDayBoundsArgsList) IsNil added in v0.1.5

func (s *GetDayBoundsArgsList) IsNil() bool

func (*GetDayBoundsArgsList) Len added in v0.1.5

func (s *GetDayBoundsArgsList) Len() int

func (*GetDayBoundsArgsList) Pointers added in v0.1.5

func (s *GetDayBoundsArgsList) Pointers() []any

func (*GetDayBoundsArgsList) Schema added in v0.1.5

func (s *GetDayBoundsArgsList) Schema() []model.Field

type GetReservationArgs

type GetReservationArgs struct {
	TenantId string
	Id       string
}

func (*GetReservationArgs) DecodeFields

func (m *GetReservationArgs) DecodeFields(r model.FieldReader)

func (*GetReservationArgs) EncodeFields

func (m *GetReservationArgs) EncodeFields(w model.FieldWriter)

func (*GetReservationArgs) IsNil

func (m *GetReservationArgs) IsNil() bool

func (*GetReservationArgs) ModelName

func (m *GetReservationArgs) ModelName() string

func (*GetReservationArgs) Pointers

func (m *GetReservationArgs) Pointers() []any

func (*GetReservationArgs) Schema

func (m *GetReservationArgs) Schema() []model.Field

func (*GetReservationArgs) Validate

func (m *GetReservationArgs) Validate(action byte) error

type GetReservationArgsList

type GetReservationArgsList []*GetReservationArgs

func (*GetReservationArgsList) Append

func (s *GetReservationArgsList) Append() model.Fielder

func (*GetReservationArgsList) At

func (*GetReservationArgsList) DecodeFields

func (s *GetReservationArgsList) DecodeFields(_ model.FieldReader)

func (*GetReservationArgsList) EncodeFields

func (s *GetReservationArgsList) EncodeFields(_ model.FieldWriter)

func (*GetReservationArgsList) IsNil

func (s *GetReservationArgsList) IsNil() bool

func (*GetReservationArgsList) Len

func (s *GetReservationArgsList) Len() int

func (*GetReservationArgsList) Pointers

func (s *GetReservationArgsList) Pointers() []any

func (*GetReservationArgsList) Schema

func (s *GetReservationArgsList) Schema() []model.Field

type ListAvailabilityArgs

type ListAvailabilityArgs struct {
	TenantId string
	StaffId  string
	ConfigId string
	From     int64
	To       int64
}

func (*ListAvailabilityArgs) DecodeFields

func (m *ListAvailabilityArgs) DecodeFields(r model.FieldReader)

func (*ListAvailabilityArgs) EncodeFields

func (m *ListAvailabilityArgs) EncodeFields(w model.FieldWriter)

func (*ListAvailabilityArgs) IsNil

func (m *ListAvailabilityArgs) IsNil() bool

func (*ListAvailabilityArgs) ModelName

func (m *ListAvailabilityArgs) ModelName() string

func (*ListAvailabilityArgs) Pointers

func (m *ListAvailabilityArgs) Pointers() []any

func (*ListAvailabilityArgs) Schema

func (m *ListAvailabilityArgs) Schema() []model.Field

func (*ListAvailabilityArgs) Validate

func (m *ListAvailabilityArgs) Validate(action byte) error

type ListAvailabilityArgsList

type ListAvailabilityArgsList []*ListAvailabilityArgs

func (*ListAvailabilityArgsList) Append

func (*ListAvailabilityArgsList) At

func (*ListAvailabilityArgsList) DecodeFields

func (s *ListAvailabilityArgsList) DecodeFields(_ model.FieldReader)

func (*ListAvailabilityArgsList) EncodeFields

func (s *ListAvailabilityArgsList) EncodeFields(_ model.FieldWriter)

func (*ListAvailabilityArgsList) IsNil

func (s *ListAvailabilityArgsList) IsNil() bool

func (*ListAvailabilityArgsList) Len

func (s *ListAvailabilityArgsList) Len() int

func (*ListAvailabilityArgsList) Pointers

func (s *ListAvailabilityArgsList) Pointers() []any

func (*ListAvailabilityArgsList) Schema

func (s *ListAvailabilityArgsList) Schema() []model.Field

type ListBlocksArgs added in v0.1.5

type ListBlocksArgs struct {
	TenantId string
	StaffId  string
}

func (*ListBlocksArgs) DecodeFields added in v0.1.5

func (m *ListBlocksArgs) DecodeFields(r model.FieldReader)

func (*ListBlocksArgs) EncodeFields added in v0.1.5

func (m *ListBlocksArgs) EncodeFields(w model.FieldWriter)

func (*ListBlocksArgs) IsNil added in v0.1.5

func (m *ListBlocksArgs) IsNil() bool

func (*ListBlocksArgs) ModelName added in v0.1.5

func (m *ListBlocksArgs) ModelName() string

func (*ListBlocksArgs) Pointers added in v0.1.5

func (m *ListBlocksArgs) Pointers() []any

func (*ListBlocksArgs) Schema added in v0.1.5

func (m *ListBlocksArgs) Schema() []model.Field

func (*ListBlocksArgs) Validate added in v0.1.5

func (m *ListBlocksArgs) Validate(action byte) error

type ListBlocksArgsList added in v0.1.5

type ListBlocksArgsList []*ListBlocksArgs

func (*ListBlocksArgsList) Append added in v0.1.5

func (s *ListBlocksArgsList) Append() model.Fielder

func (*ListBlocksArgsList) At added in v0.1.5

func (*ListBlocksArgsList) DecodeFields added in v0.1.5

func (s *ListBlocksArgsList) DecodeFields(_ model.FieldReader)

func (*ListBlocksArgsList) EncodeFields added in v0.1.5

func (s *ListBlocksArgsList) EncodeFields(_ model.FieldWriter)

func (*ListBlocksArgsList) IsNil added in v0.1.5

func (s *ListBlocksArgsList) IsNil() bool

func (*ListBlocksArgsList) Len added in v0.1.5

func (s *ListBlocksArgsList) Len() int

func (*ListBlocksArgsList) Pointers added in v0.1.5

func (s *ListBlocksArgsList) Pointers() []any

func (*ListBlocksArgsList) Schema added in v0.1.5

func (s *ListBlocksArgsList) Schema() []model.Field

type ListConflictingReservationsArgs added in v0.1.5

type ListConflictingReservationsArgs struct {
	TenantId string
	StaffId  string
	From     int64
}

func (*ListConflictingReservationsArgs) DecodeFields added in v0.1.5

func (*ListConflictingReservationsArgs) EncodeFields added in v0.1.5

func (*ListConflictingReservationsArgs) IsNil added in v0.1.5

func (*ListConflictingReservationsArgs) ModelName added in v0.1.5

func (m *ListConflictingReservationsArgs) ModelName() string

func (*ListConflictingReservationsArgs) Pointers added in v0.1.5

func (m *ListConflictingReservationsArgs) Pointers() []any

func (*ListConflictingReservationsArgs) Schema added in v0.1.5

func (*ListConflictingReservationsArgs) Validate added in v0.1.5

func (m *ListConflictingReservationsArgs) Validate(action byte) error

type ListConflictingReservationsArgsList added in v0.1.5

type ListConflictingReservationsArgsList []*ListConflictingReservationsArgs

func (*ListConflictingReservationsArgsList) Append added in v0.1.5

func (*ListConflictingReservationsArgsList) At added in v0.1.5

func (*ListConflictingReservationsArgsList) DecodeFields added in v0.1.5

func (*ListConflictingReservationsArgsList) EncodeFields added in v0.1.5

func (*ListConflictingReservationsArgsList) IsNil added in v0.1.5

func (*ListConflictingReservationsArgsList) Len added in v0.1.5

func (*ListConflictingReservationsArgsList) Pointers added in v0.1.5

func (s *ListConflictingReservationsArgsList) Pointers() []any

func (*ListConflictingReservationsArgsList) Schema added in v0.1.5

type ListExceptionsArgs added in v0.1.4

type ListExceptionsArgs struct {
	TenantId string
	StaffId  string
	From     int64
	To       int64
}

func (*ListExceptionsArgs) DecodeFields added in v0.1.4

func (m *ListExceptionsArgs) DecodeFields(r model.FieldReader)

func (*ListExceptionsArgs) EncodeFields added in v0.1.4

func (m *ListExceptionsArgs) EncodeFields(w model.FieldWriter)

func (*ListExceptionsArgs) IsNil added in v0.1.4

func (m *ListExceptionsArgs) IsNil() bool

func (*ListExceptionsArgs) ModelName added in v0.1.4

func (m *ListExceptionsArgs) ModelName() string

func (*ListExceptionsArgs) Pointers added in v0.1.4

func (m *ListExceptionsArgs) Pointers() []any

func (*ListExceptionsArgs) Schema added in v0.1.4

func (m *ListExceptionsArgs) Schema() []model.Field

func (*ListExceptionsArgs) Validate added in v0.1.4

func (m *ListExceptionsArgs) Validate(action byte) error

type ListExceptionsArgsList added in v0.1.4

type ListExceptionsArgsList []*ListExceptionsArgs

func (*ListExceptionsArgsList) Append added in v0.1.4

func (s *ListExceptionsArgsList) Append() model.Fielder

func (*ListExceptionsArgsList) At added in v0.1.4

func (*ListExceptionsArgsList) DecodeFields added in v0.1.4

func (s *ListExceptionsArgsList) DecodeFields(_ model.FieldReader)

func (*ListExceptionsArgsList) EncodeFields added in v0.1.4

func (s *ListExceptionsArgsList) EncodeFields(_ model.FieldWriter)

func (*ListExceptionsArgsList) IsNil added in v0.1.4

func (s *ListExceptionsArgsList) IsNil() bool

func (*ListExceptionsArgsList) Len added in v0.1.4

func (s *ListExceptionsArgsList) Len() int

func (*ListExceptionsArgsList) Pointers added in v0.1.4

func (s *ListExceptionsArgsList) Pointers() []any

func (*ListExceptionsArgsList) Schema added in v0.1.4

func (s *ListExceptionsArgsList) Schema() []model.Field

type ListReservationsByClientArgs

type ListReservationsByClientArgs struct {
	TenantId string
	ClientId string
}

func (*ListReservationsByClientArgs) DecodeFields

func (m *ListReservationsByClientArgs) DecodeFields(r model.FieldReader)

func (*ListReservationsByClientArgs) EncodeFields

func (m *ListReservationsByClientArgs) EncodeFields(w model.FieldWriter)

func (*ListReservationsByClientArgs) IsNil

func (*ListReservationsByClientArgs) ModelName

func (m *ListReservationsByClientArgs) ModelName() string

func (*ListReservationsByClientArgs) Pointers

func (m *ListReservationsByClientArgs) Pointers() []any

func (*ListReservationsByClientArgs) Schema

func (*ListReservationsByClientArgs) Validate

func (m *ListReservationsByClientArgs) Validate(action byte) error

type ListReservationsByClientArgsList

type ListReservationsByClientArgsList []*ListReservationsByClientArgs

func (*ListReservationsByClientArgsList) Append

func (*ListReservationsByClientArgsList) At

func (*ListReservationsByClientArgsList) DecodeFields

func (*ListReservationsByClientArgsList) EncodeFields

func (*ListReservationsByClientArgsList) IsNil

func (*ListReservationsByClientArgsList) Len

func (*ListReservationsByClientArgsList) Pointers

func (s *ListReservationsByClientArgsList) Pointers() []any

func (*ListReservationsByClientArgsList) Schema

type ListReservationsByStaffArgs

type ListReservationsByStaffArgs struct {
	TenantId string
	StaffId  string
	From     int64
	To       int64
}

func (*ListReservationsByStaffArgs) DecodeFields

func (m *ListReservationsByStaffArgs) DecodeFields(r model.FieldReader)

func (*ListReservationsByStaffArgs) EncodeFields

func (m *ListReservationsByStaffArgs) EncodeFields(w model.FieldWriter)

func (*ListReservationsByStaffArgs) IsNil

func (m *ListReservationsByStaffArgs) IsNil() bool

func (*ListReservationsByStaffArgs) ModelName

func (m *ListReservationsByStaffArgs) ModelName() string

func (*ListReservationsByStaffArgs) Pointers

func (m *ListReservationsByStaffArgs) Pointers() []any

func (*ListReservationsByStaffArgs) Schema

func (m *ListReservationsByStaffArgs) Schema() []model.Field

func (*ListReservationsByStaffArgs) Validate

func (m *ListReservationsByStaffArgs) Validate(action byte) error

type ListReservationsByStaffArgsList

type ListReservationsByStaffArgsList []*ListReservationsByStaffArgs

func (*ListReservationsByStaffArgsList) Append

func (*ListReservationsByStaffArgsList) At

func (*ListReservationsByStaffArgsList) DecodeFields

func (*ListReservationsByStaffArgsList) EncodeFields

func (*ListReservationsByStaffArgsList) IsNil

func (*ListReservationsByStaffArgsList) Len

func (*ListReservationsByStaffArgsList) Pointers

func (s *ListReservationsByStaffArgsList) Pointers() []any

func (*ListReservationsByStaffArgsList) Schema

type MarkWorkingDaysArgs added in v0.1.5

type MarkWorkingDaysArgs struct {
	TenantId string
	StaffId  string
	Dates    []int
	StartMin int64
	EndMin   int64
}

func (*MarkWorkingDaysArgs) DecodeFields added in v0.1.5

func (m *MarkWorkingDaysArgs) DecodeFields(r model.FieldReader)

func (*MarkWorkingDaysArgs) EncodeFields added in v0.1.5

func (m *MarkWorkingDaysArgs) EncodeFields(w model.FieldWriter)

func (*MarkWorkingDaysArgs) IsNil added in v0.1.5

func (m *MarkWorkingDaysArgs) IsNil() bool

func (*MarkWorkingDaysArgs) ModelName added in v0.1.5

func (m *MarkWorkingDaysArgs) ModelName() string

func (*MarkWorkingDaysArgs) Pointers added in v0.1.5

func (m *MarkWorkingDaysArgs) Pointers() []any

func (*MarkWorkingDaysArgs) Schema added in v0.1.5

func (m *MarkWorkingDaysArgs) Schema() []model.Field

func (*MarkWorkingDaysArgs) Validate added in v0.1.5

func (m *MarkWorkingDaysArgs) Validate(action byte) error

type MarkWorkingDaysArgsList added in v0.1.5

type MarkWorkingDaysArgsList []*MarkWorkingDaysArgs

func (*MarkWorkingDaysArgsList) Append added in v0.1.5

func (*MarkWorkingDaysArgsList) At added in v0.1.5

func (*MarkWorkingDaysArgsList) DecodeFields added in v0.1.5

func (s *MarkWorkingDaysArgsList) DecodeFields(_ model.FieldReader)

func (*MarkWorkingDaysArgsList) EncodeFields added in v0.1.5

func (s *MarkWorkingDaysArgsList) EncodeFields(_ model.FieldWriter)

func (*MarkWorkingDaysArgsList) IsNil added in v0.1.5

func (s *MarkWorkingDaysArgsList) IsNil() bool

func (*MarkWorkingDaysArgsList) Len added in v0.1.5

func (s *MarkWorkingDaysArgsList) Len() int

func (*MarkWorkingDaysArgsList) Pointers added in v0.1.5

func (s *MarkWorkingDaysArgsList) Pointers() []any

func (*MarkWorkingDaysArgsList) Schema added in v0.1.5

func (s *MarkWorkingDaysArgsList) Schema() []model.Field

type Module

type Module struct {
	// contains filtered or unexported fields
}

func New

func New(db *orm.DB, deps Deps) (*Module, error)

func (*Module) AddException

func (m *Module) AddException(exc WorkCalendarException) error

func (*Module) ChangeReservationStatus

func (m *Module) ChangeReservationStatus(cmd ChangeStatusCmd) error

func (*Module) CreateReservation

func (m *Module) CreateReservation(cmd CreateReservationCmd) (Reservation, error)

func (*Module) ExpirePendingReservations

func (m *Module) ExpirePendingReservations(tenantId string, before int64) (int, error)

func (*Module) GetDayBounds added in v0.1.5

func (m *Module) GetDayBounds(date int64) (tinytime.DayBounds, error)

GetDayBounds proxies Deps.Bounds para que el editor acote sus propios controles llamando a este módulo, no al calendario institucional directamente (§6.2).

func (*Module) GetReservation

func (m *Module) GetReservation(tenantId, id string) (Reservation, error)

func (*Module) IconSvg

func (m *Module) IconSvg() *sprite.Sprite

IconSvg registra el ícono de marca del módulo. tinywasm/ssr lo extrae durante SSR y assetmin lo inyecta inline en <body> — nunca se llama a mano.

func (*Module) ListAvailability

func (m *Module) ListAvailability(tenantId, staffId, configId string, from, to int64) ([]TimeSlot, error)

func (*Module) ListBlocks added in v0.1.5

func (m *Module) ListBlocks(tenantId, staffId string) ([]WorkCalendarBlock, error)

func (*Module) ListConflictingReservations added in v0.1.5

func (m *Module) ListConflictingReservations(tenantId, staffId string, from int64) ([]ConflictingReservation, error)

ListConflictingReservations returns future reservations that the CURRENT schedule no longer covers. from is normally "now". Son las que una edición de agenda o del establecimiento dejó huérfanas — el worklist de CU-17. Reported, never cancelled: cancelling on the patient's behalf is a decision for a person.

func (*Module) ListExceptions added in v0.1.4

func (m *Module) ListExceptions(tenantId, staffId string, from, to int64) ([]WorkCalendarException, error)

func (*Module) ListReservationsByClient

func (m *Module) ListReservationsByClient(tenantId, clientId string) ([]Reservation, error)

func (*Module) ListReservationsByStaff

func (m *Module) ListReservationsByStaff(tenantId, staffId string, from, to int64) ([]Reservation, error)

func (*Module) MarkWorkingDays added in v0.1.5

func (m *Module) MarkWorkingDays(tenantId, staffId string, dates []int64, startMin, endMin int) error

MarkWorkingDays writes ONE dated block per date, all with the same window — the bulk gesture behind "mark the days I work over the next 6 months" (CU-10/CU-11). Re-marking a date replaces its blocks.

func (*Module) ModelName

func (m *Module) ModelName() string

func (*Module) MountOperations added in v0.1.3

func (m *Module) MountOperations(reg router.OperationRegistry)

func (*Module) RecomputeConflicts added in v0.1.5

func (m *Module) RecomputeConflicts(tenantId string, from, to int64) (int, error)

RecomputeConflicts re-evaluates every future reservation in [from, to] against the CURRENT schedule and bounds, marking or clearing CONFLICTED as the answer dictates. Returns how many reservations changed state.

It is idempotent: calling it twice with no intervening change is a no-op and publishes nothing (CU-19/CU-29 depend on that).

tenantId scopes it; from/to are midnight UTC seconds. to == 0 means "the module's full forward horizon", which is what a weekly-hours change needs since it has no bounded date range.

El disparador queda INVERTIDO (§8.4): no hay Subscriber aquí — la aplicación, que legítimamente conoce ambos módulos, se suscribe al calendario del establecimiento y llama a esto.

func (*Module) RemoveException

func (m *Module) RemoveException(tenantId, exceptionId string) error

func (*Module) SaveDateBlocks added in v0.1.5

func (m *Module) SaveDateBlocks(tenantId, staffId string, date int64, blocks []WorkCalendarBlock) error

SaveDateBlocks replaces the dated blocks of ONE date, so a single marked day can diverge from the common window it was created with (CU-11).

func (*Module) SaveDayBlocks added in v0.1.5

func (m *Module) SaveDayBlocks(tenantId, staffId string, dayOfWeek int, blocks []WorkCalendarBlock) error

SaveDayBlocks replaces EVERY weekly block of that weekday with the ones given. A whole-day replace, not a per-row upsert: partial edits are what let the stored set drift out of step with what the editor is showing.

func (*Module) UnmarkWorkingDays added in v0.1.5

func (m *Module) UnmarkWorkingDays(tenantId, staffId string, dates []int64) error

UnmarkWorkingDays deletes every dated block on those dates, returning the days to whatever the weekly template says — or to unworked (CU-15).

func (*Module) UpsertCalendarConfig

func (m *Module) UpsertCalendarConfig(cfg WorkCalendarConfig) error

type RecomputeConflictsArgs added in v0.1.5

type RecomputeConflictsArgs struct {
	TenantId string
	From     int64
	To       int64
}

func (*RecomputeConflictsArgs) DecodeFields added in v0.1.5

func (m *RecomputeConflictsArgs) DecodeFields(r model.FieldReader)

func (*RecomputeConflictsArgs) EncodeFields added in v0.1.5

func (m *RecomputeConflictsArgs) EncodeFields(w model.FieldWriter)

func (*RecomputeConflictsArgs) IsNil added in v0.1.5

func (m *RecomputeConflictsArgs) IsNil() bool

func (*RecomputeConflictsArgs) ModelName added in v0.1.5

func (m *RecomputeConflictsArgs) ModelName() string

func (*RecomputeConflictsArgs) Pointers added in v0.1.5

func (m *RecomputeConflictsArgs) Pointers() []any

func (*RecomputeConflictsArgs) Schema added in v0.1.5

func (m *RecomputeConflictsArgs) Schema() []model.Field

func (*RecomputeConflictsArgs) Validate added in v0.1.5

func (m *RecomputeConflictsArgs) Validate(action byte) error

type RecomputeConflictsArgsList added in v0.1.5

type RecomputeConflictsArgsList []*RecomputeConflictsArgs

func (*RecomputeConflictsArgsList) Append added in v0.1.5

func (*RecomputeConflictsArgsList) At added in v0.1.5

func (*RecomputeConflictsArgsList) DecodeFields added in v0.1.5

func (s *RecomputeConflictsArgsList) DecodeFields(_ model.FieldReader)

func (*RecomputeConflictsArgsList) EncodeFields added in v0.1.5

func (s *RecomputeConflictsArgsList) EncodeFields(_ model.FieldWriter)

func (*RecomputeConflictsArgsList) IsNil added in v0.1.5

func (s *RecomputeConflictsArgsList) IsNil() bool

func (*RecomputeConflictsArgsList) Len added in v0.1.5

func (*RecomputeConflictsArgsList) Pointers added in v0.1.5

func (s *RecomputeConflictsArgsList) Pointers() []any

func (*RecomputeConflictsArgsList) Schema added in v0.1.5

func (s *RecomputeConflictsArgsList) Schema() []model.Field

type RemoveCalendarExceptionArgs

type RemoveCalendarExceptionArgs struct {
	TenantId    string
	ExceptionId string
}

func (*RemoveCalendarExceptionArgs) DecodeFields

func (m *RemoveCalendarExceptionArgs) DecodeFields(r model.FieldReader)

func (*RemoveCalendarExceptionArgs) EncodeFields

func (m *RemoveCalendarExceptionArgs) EncodeFields(w model.FieldWriter)

func (*RemoveCalendarExceptionArgs) IsNil

func (m *RemoveCalendarExceptionArgs) IsNil() bool

func (*RemoveCalendarExceptionArgs) ModelName

func (m *RemoveCalendarExceptionArgs) ModelName() string

func (*RemoveCalendarExceptionArgs) Pointers

func (m *RemoveCalendarExceptionArgs) Pointers() []any

func (*RemoveCalendarExceptionArgs) Schema

func (m *RemoveCalendarExceptionArgs) Schema() []model.Field

func (*RemoveCalendarExceptionArgs) Validate

func (m *RemoveCalendarExceptionArgs) Validate(action byte) error

type RemoveCalendarExceptionArgsList

type RemoveCalendarExceptionArgsList []*RemoveCalendarExceptionArgs

func (*RemoveCalendarExceptionArgsList) Append

func (*RemoveCalendarExceptionArgsList) At

func (*RemoveCalendarExceptionArgsList) DecodeFields

func (*RemoveCalendarExceptionArgsList) EncodeFields

func (*RemoveCalendarExceptionArgsList) IsNil

func (*RemoveCalendarExceptionArgsList) Len

func (*RemoveCalendarExceptionArgsList) Pointers

func (s *RemoveCalendarExceptionArgsList) Pointers() []any

func (*RemoveCalendarExceptionArgsList) Schema

type Repository

type Repository struct {
	// contains filtered or unexported fields
}

Repository provee operaciones CRUD para todas las tablas de appointment-booking.

func NewRepository

func NewRepository(db *orm.DB, ids model.IDGenerator) (*Repository, error)

NewRepository crea un nuevo Repository y migra sus 5 tablas propias cuando el backend soporta DDL (no-op contra storage/mem, usado por las pruebas propias de este módulo).

func (*Repository) DeleteDateBlocks added in v0.1.5

func (r *Repository) DeleteDateBlocks(tenantId, staffId string, date int64) error

DeleteDateBlocks borra todos los bloques datados de esas fechas (CU-15: devuelve el día a lo que diga el template semanal, o a des-trabajado).

func (*Repository) DeleteException

func (r *Repository) DeleteException(tenantId, id string) error

func (*Repository) GetCalendarConfig

func (r *Repository) GetCalendarConfig(tenantId, staffId string) (WorkCalendarConfig, error)

func (*Repository) GetEmployeeServiceConfig

func (r *Repository) GetEmployeeServiceConfig(id string) (EmployeeServiceConfig, error)

func (*Repository) GetException added in v0.1.4

func (r *Repository) GetException(tenantId, id string) (WorkCalendarException, error)

func (*Repository) GetReservation

func (r *Repository) GetReservation(id string) (Reservation, error)

func (*Repository) GetReservationTx

func (r *Repository) GetReservationTx(tx *orm.DB, tenantId, id string) (Reservation, error)

func (*Repository) InsertEmployeeServiceConfig

func (r *Repository) InsertEmployeeServiceConfig(cfg EmployeeServiceConfig) error

func (*Repository) InsertException

func (r *Repository) InsertException(exc WorkCalendarException) error

func (*Repository) InsertReservation

func (r *Repository) InsertReservation(res *Reservation) error

func (*Repository) ListBlocks added in v0.1.5

func (r *Repository) ListBlocks(tenantId, staffId string) ([]WorkCalendarBlock, error)

ListBlocks devuelve todos los bloques de un staff — semanales y datados mezclados; ListAvailability los separa por fecha/weekday con las helpers del servicio.

func (*Repository) ListEmployeeServiceConfigByStaff

func (r *Repository) ListEmployeeServiceConfigByStaff(tenantId, staffId string) ([]EmployeeServiceConfig, error)

func (*Repository) ListExceptions

func (r *Repository) ListExceptions(tenantId, staffId string, from, to int64) ([]WorkCalendarException, error)

func (*Repository) ListReservationsByClient

func (r *Repository) ListReservationsByClient(tenantId, clientId string) ([]Reservation, error)

func (*Repository) ListReservationsByStaff

func (r *Repository) ListReservationsByStaff(tenantId, staffId string, from, to int64) ([]Reservation, error)

func (*Repository) ListReservationsByTenantRange added in v0.1.5

func (r *Repository) ListReservationsByTenantRange(tenantId string, from, to int64) ([]Reservation, error)

ListReservationsByTenantRange lista las reservas de todo un tenant en un rango de fechas — el alcance del recompute del establecimiento (un feriado golpea a todos los profesionales a la vez).

func (*Repository) ReplaceDateBlocks added in v0.1.5

func (r *Repository) ReplaceDateBlocks(tenantId, staffId string, date int64, blocks []WorkCalendarBlock) error

ReplaceDateBlocks pisa los bloques DATADOS de una fecha (CU-11: un día marcado puede divergir de la ventana común con la que se creó).

func (*Repository) ReplaceWeekdayBlocks added in v0.1.5

func (r *Repository) ReplaceWeekdayBlocks(tenantId, staffId string, dayOfWeek int, blocks []WorkCalendarBlock) error

ReplaceWeekdayBlocks pisa todos los bloques semanales del weekday dado — un replace de día completo, no un upsert por fila: los edits parciales son lo que desincroniza el conjunto guardado de lo que muestra el editor (§7).

func (*Repository) UpdateEmployeeServiceConfig

func (r *Repository) UpdateEmployeeServiceConfig(cfg EmployeeServiceConfig) error

func (*Repository) UpdateReservationConflictTx added in v0.1.5

func (r *Repository) UpdateReservationConflictTx(tx *orm.DB, id, tenantId, status, statusBefore, updatedBy string, updatedAt int64, expectedRevision int64) error

UpdateReservationConflictTx escribe el estado CONFLICTED (o su restauración) con optimismo: WHERE revision = N y tenant scope en ambas ramas. statusBefore queda grabado al entrar en conflicto y "" al salir (fuente única de restauración, §8.5).

func (*Repository) UpdateReservationStatus

func (r *Repository) UpdateReservationStatus(id, status, updatedBy string, updatedAt int64, expectedRevision int64) error

func (*Repository) UpdateReservationStatusTx

func (r *Repository) UpdateReservationStatusTx(tx *orm.DB, id, status, updatedBy string, updatedAt int64, expectedRevision int64) error

func (*Repository) UpsertCalendarConfig

func (r *Repository) UpsertCalendarConfig(cfg WorkCalendarConfig) error

type Reservation

type Reservation struct {
	Id                      string
	TenantId                string
	ClientId                string
	CreatorUserId           string
	EmployeeServiceConfigId string
	StaffIdsnapshot         string
	ServiceIdsnapshot       string
	DurationMinSnapshot     int64
	PriceSnapshot           float64
	CurrencySnapshot        string
	ReservationDate         int64
	ReservationTime         int64
	LocalStringDate         string
	LocalStringTime         string
	Status                  string
	RescheduledFromId       string
	StatusBeforeConflict    string
	PaymentId               string
	Notes                   string
	UpdatedAt               int64
	UpdatedBy               string
	Revision                int64
}

func ReadOneReservation

func ReadOneReservation(qb *orm.QB, model *Reservation) (*Reservation, error)

func (*Reservation) DecodeFields

func (m *Reservation) DecodeFields(r model.FieldReader)

func (*Reservation) EncodeFields

func (m *Reservation) EncodeFields(w model.FieldWriter)

func (*Reservation) IsNil

func (m *Reservation) IsNil() bool

func (*Reservation) Item added in v0.1.1

func (r *Reservation) Item() view.Item

Item implementa view.Itemizer — el ÚNICO código específico de view que carga este registro. El Presenter indexa las filas por ID a partir de esto durante Reload; no hay lookup manual byId/WithFill.

func (*Reservation) ModelName

func (m *Reservation) ModelName() string

func (*Reservation) Pointers

func (m *Reservation) Pointers() []any

func (*Reservation) Schema

func (m *Reservation) Schema() []model.Field

func (*Reservation) Validate

func (m *Reservation) Validate(action byte) error

type ReservationList

type ReservationList []*Reservation

func ReadAllReservation

func ReadAllReservation(qb *orm.QB) (ReservationList, error)

func (*ReservationList) Append

func (s *ReservationList) Append() model.Fielder

func (*ReservationList) At

func (s *ReservationList) At(i int) model.Fielder

func (*ReservationList) DecodeFields

func (s *ReservationList) DecodeFields(_ model.FieldReader)

func (*ReservationList) EncodeFields

func (s *ReservationList) EncodeFields(_ model.FieldWriter)

func (*ReservationList) IsNil

func (s *ReservationList) IsNil() bool

func (*ReservationList) Len

func (s *ReservationList) Len() int

func (*ReservationList) Pointers

func (s *ReservationList) Pointers() []any

func (*ReservationList) Schema

func (s *ReservationList) Schema() []model.Field

type SaveDateBlocksArgs added in v0.1.5

type SaveDateBlocksArgs struct {
	TenantId     string
	StaffId      string
	SpecificDate int64
	Blocks       []WorkCalendarBlock
}

func (*SaveDateBlocksArgs) DecodeFields added in v0.1.5

func (m *SaveDateBlocksArgs) DecodeFields(r model.FieldReader)

func (*SaveDateBlocksArgs) EncodeFields added in v0.1.5

func (m *SaveDateBlocksArgs) EncodeFields(w model.FieldWriter)

func (*SaveDateBlocksArgs) IsNil added in v0.1.5

func (m *SaveDateBlocksArgs) IsNil() bool

func (*SaveDateBlocksArgs) ModelName added in v0.1.5

func (m *SaveDateBlocksArgs) ModelName() string

func (*SaveDateBlocksArgs) Pointers added in v0.1.5

func (m *SaveDateBlocksArgs) Pointers() []any

func (*SaveDateBlocksArgs) Schema added in v0.1.5

func (m *SaveDateBlocksArgs) Schema() []model.Field

func (*SaveDateBlocksArgs) Validate added in v0.1.5

func (m *SaveDateBlocksArgs) Validate(action byte) error

type SaveDateBlocksArgsList added in v0.1.5

type SaveDateBlocksArgsList []*SaveDateBlocksArgs

func (*SaveDateBlocksArgsList) Append added in v0.1.5

func (s *SaveDateBlocksArgsList) Append() model.Fielder

func (*SaveDateBlocksArgsList) At added in v0.1.5

func (*SaveDateBlocksArgsList) DecodeFields added in v0.1.5

func (s *SaveDateBlocksArgsList) DecodeFields(_ model.FieldReader)

func (*SaveDateBlocksArgsList) EncodeFields added in v0.1.5

func (s *SaveDateBlocksArgsList) EncodeFields(_ model.FieldWriter)

func (*SaveDateBlocksArgsList) IsNil added in v0.1.5

func (s *SaveDateBlocksArgsList) IsNil() bool

func (*SaveDateBlocksArgsList) Len added in v0.1.5

func (s *SaveDateBlocksArgsList) Len() int

func (*SaveDateBlocksArgsList) Pointers added in v0.1.5

func (s *SaveDateBlocksArgsList) Pointers() []any

func (*SaveDateBlocksArgsList) Schema added in v0.1.5

func (s *SaveDateBlocksArgsList) Schema() []model.Field

type SaveDayBlocksArgs added in v0.1.5

type SaveDayBlocksArgs struct {
	TenantId  string
	StaffId   string
	DayOfWeek int64
	Blocks    []WorkCalendarBlock
}

func (*SaveDayBlocksArgs) DecodeFields added in v0.1.5

func (m *SaveDayBlocksArgs) DecodeFields(r model.FieldReader)

func (*SaveDayBlocksArgs) EncodeFields added in v0.1.5

func (m *SaveDayBlocksArgs) EncodeFields(w model.FieldWriter)

func (*SaveDayBlocksArgs) IsNil added in v0.1.5

func (m *SaveDayBlocksArgs) IsNil() bool

func (*SaveDayBlocksArgs) ModelName added in v0.1.5

func (m *SaveDayBlocksArgs) ModelName() string

func (*SaveDayBlocksArgs) Pointers added in v0.1.5

func (m *SaveDayBlocksArgs) Pointers() []any

func (*SaveDayBlocksArgs) Schema added in v0.1.5

func (m *SaveDayBlocksArgs) Schema() []model.Field

func (*SaveDayBlocksArgs) Validate added in v0.1.5

func (m *SaveDayBlocksArgs) Validate(action byte) error

type SaveDayBlocksArgsList added in v0.1.5

type SaveDayBlocksArgsList []*SaveDayBlocksArgs

func (*SaveDayBlocksArgsList) Append added in v0.1.5

func (s *SaveDayBlocksArgsList) Append() model.Fielder

func (*SaveDayBlocksArgsList) At added in v0.1.5

func (*SaveDayBlocksArgsList) DecodeFields added in v0.1.5

func (s *SaveDayBlocksArgsList) DecodeFields(_ model.FieldReader)

func (*SaveDayBlocksArgsList) EncodeFields added in v0.1.5

func (s *SaveDayBlocksArgsList) EncodeFields(_ model.FieldWriter)

func (*SaveDayBlocksArgsList) IsNil added in v0.1.5

func (s *SaveDayBlocksArgsList) IsNil() bool

func (*SaveDayBlocksArgsList) Len added in v0.1.5

func (s *SaveDayBlocksArgsList) Len() int

func (*SaveDayBlocksArgsList) Pointers added in v0.1.5

func (s *SaveDayBlocksArgsList) Pointers() []any

func (*SaveDayBlocksArgsList) Schema added in v0.1.5

func (s *SaveDayBlocksArgsList) Schema() []model.Field

type ScheduleChangedPayload added in v0.1.4

type ScheduleChangedPayload struct {
	TenantId string
	StaffId  string
	// FromDate/ToDate bound what changed, so a consumer recomputes a range
	// instead of everything. 0/0 means "unknown, recompute all".
	FromDate int64
	ToDate   int64
	// ConflictCount is how many reservations the change put in conflict.
	// Zero means nobody needs to be told (CU-19).
	ConflictCount int
}

ScheduleChangedPayload es el payload tipado del evento EventScheduleChanged. Implementa model.Encodable (lo que events.Event.Payload exige) y también model.Decodable, para que un broker que cruza un cable real (webtyp/sse en mjosefa-cms) pueda serializarlo; el broker in-proc de la demo entrega el puntero concreto sin codificar.

func (*ScheduleChangedPayload) DecodeFields added in v0.1.4

func (p *ScheduleChangedPayload) DecodeFields(r model.FieldReader)

func (*ScheduleChangedPayload) EncodeFields added in v0.1.4

func (p *ScheduleChangedPayload) EncodeFields(w model.FieldWriter)

func (*ScheduleChangedPayload) IsNil added in v0.1.4

func (p *ScheduleChangedPayload) IsNil() bool

type ScheduleClient added in v0.1.4

type ScheduleClient struct {
	// contains filtered or unexported fields
}

ScheduleClient es la vista caller-side de la agenda de UN profesional: la contraparte tipada de las ops de calendario, para que una app adapte a scheduleeditor sin importar un transport. Importa solo router + los tipos de este paquete — este módulo no puede importar components/layout (blacklist de renderer).

func NewScheduleClient added in v0.1.4

func NewScheduleClient(caller router.Caller, tenantId, staffId string) *ScheduleClient

NewScheduleClient construye el cliente para la agenda de (tenantId, staffId).

func (*ScheduleClient) AddException added in v0.1.4

func (c *ScheduleClient) AddException(exc WorkCalendarException, done func(error))

AddException da de alta una excepción de calendario.

func (*ScheduleClient) Blocks added in v0.1.5

func (c *ScheduleClient) Blocks(done func([]WorkCalendarBlock, error))

Blocks carga todos los bloques del profesional (semanales y datados).

func (*ScheduleClient) Exceptions added in v0.1.4

func (c *ScheduleClient) Exceptions(from, to int64, done func([]WorkCalendarException, error))

Exceptions carga las excepciones del rango [from, to] (medianoche UTC, inclusive).

func (*ScheduleClient) RemoveException added in v0.1.4

func (c *ScheduleClient) RemoveException(exceptionId string, done func(error))

RemoveException da de baja una excepción por id.

func (*ScheduleClient) SaveDayBlocks added in v0.1.5

func (c *ScheduleClient) SaveDayBlocks(dayOfWeek int, blocks []WorkCalendarBlock, done func(error))

SaveDayBlocks pisa todos los bloques semanales del weekday dado.

type SchedulingService

type SchedulingService interface {
	// Gestión de calendario
	UpsertCalendarConfig(cfg WorkCalendarConfig) error
	SaveDayBlocks(tenantId, staffId string, dayOfWeek int, blocks []WorkCalendarBlock) error
	SaveDateBlocks(tenantId, staffId string, date int64, blocks []WorkCalendarBlock) error
	MarkWorkingDays(tenantId, staffId string, dates []int64, startMin, endMin int) error
	UnmarkWorkingDays(tenantId, staffId string, dates []int64) error
	ListBlocks(tenantId, staffId string) ([]WorkCalendarBlock, error)
	AddException(exc WorkCalendarException) error
	RemoveException(tenantId, exceptionId string) error
	ListExceptions(tenantId, staffId string, from, to int64) ([]WorkCalendarException, error)
	GetDayBounds(date int64) (tinytime.DayBounds, error)

	// Disponibilidad
	ListAvailability(tenantId, staffId, configId string, from, to int64) ([]TimeSlot, error)

	// Reservas
	CreateReservation(cmd CreateReservationCmd) (Reservation, error)
	GetReservation(tenantId, id string) (Reservation, error)
	ListReservationsByStaff(tenantId, staffId string, from, to int64) ([]Reservation, error)
	ListReservationsByClient(tenantId, clientId string) ([]Reservation, error)
	ChangeReservationStatus(cmd ChangeStatusCmd) error
	ExpirePendingReservations(tenantId string, before int64) (int, error)

	// Conflictos
	ListConflictingReservations(tenantId, staffId string, from int64) ([]ConflictingReservation, error)
	RecomputeConflicts(tenantId string, from, to int64) (int, error)
}

type StaffReader

type StaffReader interface {
	StaffExists(tenantId, staffId string) (bool, error)
}

StaffReader verifica que un miembro del staff existe y pertenece al tenant.

type TimeSlot

type TimeSlot struct {
	StartUtc int64
	EndUtc   int64
}

func (*TimeSlot) DecodeFields

func (m *TimeSlot) DecodeFields(r model.FieldReader)

func (*TimeSlot) EncodeFields

func (m *TimeSlot) EncodeFields(w model.FieldWriter)

func (*TimeSlot) IsNil

func (m *TimeSlot) IsNil() bool

func (*TimeSlot) ModelName

func (m *TimeSlot) ModelName() string

func (*TimeSlot) Pointers

func (m *TimeSlot) Pointers() []any

func (*TimeSlot) Schema

func (m *TimeSlot) Schema() []model.Field

func (*TimeSlot) Validate

func (m *TimeSlot) Validate(action byte) error

type TimeSlotList

type TimeSlotList []*TimeSlot

func (*TimeSlotList) Append

func (s *TimeSlotList) Append() model.Fielder

func (*TimeSlotList) At

func (s *TimeSlotList) At(i int) model.Fielder

func (*TimeSlotList) DecodeFields

func (s *TimeSlotList) DecodeFields(_ model.FieldReader)

func (*TimeSlotList) EncodeFields

func (s *TimeSlotList) EncodeFields(_ model.FieldWriter)

func (*TimeSlotList) IsNil

func (s *TimeSlotList) IsNil() bool

func (*TimeSlotList) Len

func (s *TimeSlotList) Len() int

func (*TimeSlotList) Pointers

func (s *TimeSlotList) Pointers() []any

func (*TimeSlotList) Schema

func (s *TimeSlotList) Schema() []model.Field

type UnmarkWorkingDaysArgs added in v0.1.5

type UnmarkWorkingDaysArgs struct {
	TenantId string
	StaffId  string
	Dates    []int
}

func (*UnmarkWorkingDaysArgs) DecodeFields added in v0.1.5

func (m *UnmarkWorkingDaysArgs) DecodeFields(r model.FieldReader)

func (*UnmarkWorkingDaysArgs) EncodeFields added in v0.1.5

func (m *UnmarkWorkingDaysArgs) EncodeFields(w model.FieldWriter)

func (*UnmarkWorkingDaysArgs) IsNil added in v0.1.5

func (m *UnmarkWorkingDaysArgs) IsNil() bool

func (*UnmarkWorkingDaysArgs) ModelName added in v0.1.5

func (m *UnmarkWorkingDaysArgs) ModelName() string

func (*UnmarkWorkingDaysArgs) Pointers added in v0.1.5

func (m *UnmarkWorkingDaysArgs) Pointers() []any

func (*UnmarkWorkingDaysArgs) Schema added in v0.1.5

func (m *UnmarkWorkingDaysArgs) Schema() []model.Field

func (*UnmarkWorkingDaysArgs) Validate added in v0.1.5

func (m *UnmarkWorkingDaysArgs) Validate(action byte) error

type UnmarkWorkingDaysArgsList added in v0.1.5

type UnmarkWorkingDaysArgsList []*UnmarkWorkingDaysArgs

func (*UnmarkWorkingDaysArgsList) Append added in v0.1.5

func (*UnmarkWorkingDaysArgsList) At added in v0.1.5

func (*UnmarkWorkingDaysArgsList) DecodeFields added in v0.1.5

func (s *UnmarkWorkingDaysArgsList) DecodeFields(_ model.FieldReader)

func (*UnmarkWorkingDaysArgsList) EncodeFields added in v0.1.5

func (s *UnmarkWorkingDaysArgsList) EncodeFields(_ model.FieldWriter)

func (*UnmarkWorkingDaysArgsList) IsNil added in v0.1.5

func (s *UnmarkWorkingDaysArgsList) IsNil() bool

func (*UnmarkWorkingDaysArgsList) Len added in v0.1.5

func (s *UnmarkWorkingDaysArgsList) Len() int

func (*UnmarkWorkingDaysArgsList) Pointers added in v0.1.5

func (s *UnmarkWorkingDaysArgsList) Pointers() []any

func (*UnmarkWorkingDaysArgsList) Schema added in v0.1.5

func (s *UnmarkWorkingDaysArgsList) Schema() []model.Field

type UpsertCalendarConfigArgs

type UpsertCalendarConfigArgs struct {
	TenantId string
	StaffId  string
	Timezone string
	IsActive bool
}

func (*UpsertCalendarConfigArgs) DecodeFields

func (m *UpsertCalendarConfigArgs) DecodeFields(r model.FieldReader)

func (*UpsertCalendarConfigArgs) EncodeFields

func (m *UpsertCalendarConfigArgs) EncodeFields(w model.FieldWriter)

func (*UpsertCalendarConfigArgs) IsNil

func (m *UpsertCalendarConfigArgs) IsNil() bool

func (*UpsertCalendarConfigArgs) ModelName

func (m *UpsertCalendarConfigArgs) ModelName() string

func (*UpsertCalendarConfigArgs) Pointers

func (m *UpsertCalendarConfigArgs) Pointers() []any

func (*UpsertCalendarConfigArgs) Schema

func (m *UpsertCalendarConfigArgs) Schema() []model.Field

func (*UpsertCalendarConfigArgs) Validate

func (m *UpsertCalendarConfigArgs) Validate(action byte) error

type UpsertCalendarConfigArgsList

type UpsertCalendarConfigArgsList []*UpsertCalendarConfigArgs

func (*UpsertCalendarConfigArgsList) Append

func (*UpsertCalendarConfigArgsList) At

func (*UpsertCalendarConfigArgsList) DecodeFields

func (s *UpsertCalendarConfigArgsList) DecodeFields(_ model.FieldReader)

func (*UpsertCalendarConfigArgsList) EncodeFields

func (s *UpsertCalendarConfigArgsList) EncodeFields(_ model.FieldWriter)

func (*UpsertCalendarConfigArgsList) IsNil

func (*UpsertCalendarConfigArgsList) Len

func (*UpsertCalendarConfigArgsList) Pointers

func (s *UpsertCalendarConfigArgsList) Pointers() []any

func (*UpsertCalendarConfigArgsList) Schema

type WorkCalendarBlock added in v0.1.5

type WorkCalendarBlock struct {
	Id           string
	TenantId     string
	StaffId      string
	DayOfWeek    int64
	SpecificDate int64
	StartMin     int64
	EndMin       int64
	IsActive     bool
}

func ReadOneWorkCalendarBlock added in v0.1.5

func ReadOneWorkCalendarBlock(qb *orm.QB, model *WorkCalendarBlock) (*WorkCalendarBlock, error)

func (*WorkCalendarBlock) DecodeFields added in v0.1.5

func (m *WorkCalendarBlock) DecodeFields(r model.FieldReader)

func (*WorkCalendarBlock) EncodeFields added in v0.1.5

func (m *WorkCalendarBlock) EncodeFields(w model.FieldWriter)

func (*WorkCalendarBlock) IsNil added in v0.1.5

func (m *WorkCalendarBlock) IsNil() bool

func (*WorkCalendarBlock) ModelName added in v0.1.5

func (m *WorkCalendarBlock) ModelName() string

func (*WorkCalendarBlock) Pointers added in v0.1.5

func (m *WorkCalendarBlock) Pointers() []any

func (*WorkCalendarBlock) Schema added in v0.1.5

func (m *WorkCalendarBlock) Schema() []model.Field

func (*WorkCalendarBlock) Validate added in v0.1.5

func (m *WorkCalendarBlock) Validate(action byte) error

type WorkCalendarBlockList added in v0.1.5

type WorkCalendarBlockList []*WorkCalendarBlock

func ReadAllWorkCalendarBlock added in v0.1.5

func ReadAllWorkCalendarBlock(qb *orm.QB) (WorkCalendarBlockList, error)

func (*WorkCalendarBlockList) Append added in v0.1.5

func (s *WorkCalendarBlockList) Append() model.Fielder

func (*WorkCalendarBlockList) At added in v0.1.5

func (*WorkCalendarBlockList) DecodeFields added in v0.1.5

func (s *WorkCalendarBlockList) DecodeFields(_ model.FieldReader)

func (*WorkCalendarBlockList) EncodeFields added in v0.1.5

func (s *WorkCalendarBlockList) EncodeFields(_ model.FieldWriter)

func (*WorkCalendarBlockList) IsNil added in v0.1.5

func (s *WorkCalendarBlockList) IsNil() bool

func (*WorkCalendarBlockList) Len added in v0.1.5

func (s *WorkCalendarBlockList) Len() int

func (*WorkCalendarBlockList) Pointers added in v0.1.5

func (s *WorkCalendarBlockList) Pointers() []any

func (*WorkCalendarBlockList) Schema added in v0.1.5

func (s *WorkCalendarBlockList) Schema() []model.Field

type WorkCalendarConfig

type WorkCalendarConfig struct {
	Id       string
	TenantId string
	StaffId  string
	Timezone string
	IsActive bool
}

func ReadOneWorkCalendarConfig

func ReadOneWorkCalendarConfig(qb *orm.QB, model *WorkCalendarConfig) (*WorkCalendarConfig, error)

func (*WorkCalendarConfig) DecodeFields

func (m *WorkCalendarConfig) DecodeFields(r model.FieldReader)

func (*WorkCalendarConfig) EncodeFields

func (m *WorkCalendarConfig) EncodeFields(w model.FieldWriter)

func (*WorkCalendarConfig) IsNil

func (m *WorkCalendarConfig) IsNil() bool

func (*WorkCalendarConfig) ModelName

func (m *WorkCalendarConfig) ModelName() string

func (*WorkCalendarConfig) Pointers

func (m *WorkCalendarConfig) Pointers() []any

func (*WorkCalendarConfig) Schema

func (m *WorkCalendarConfig) Schema() []model.Field

func (*WorkCalendarConfig) Validate

func (m *WorkCalendarConfig) Validate(action byte) error

type WorkCalendarConfigList

type WorkCalendarConfigList []*WorkCalendarConfig

func ReadAllWorkCalendarConfig

func ReadAllWorkCalendarConfig(qb *orm.QB) (WorkCalendarConfigList, error)

func (*WorkCalendarConfigList) Append

func (s *WorkCalendarConfigList) Append() model.Fielder

func (*WorkCalendarConfigList) At

func (*WorkCalendarConfigList) DecodeFields

func (s *WorkCalendarConfigList) DecodeFields(_ model.FieldReader)

func (*WorkCalendarConfigList) EncodeFields

func (s *WorkCalendarConfigList) EncodeFields(_ model.FieldWriter)

func (*WorkCalendarConfigList) IsNil

func (s *WorkCalendarConfigList) IsNil() bool

func (*WorkCalendarConfigList) Len

func (s *WorkCalendarConfigList) Len() int

func (*WorkCalendarConfigList) Pointers

func (s *WorkCalendarConfigList) Pointers() []any

func (*WorkCalendarConfigList) Schema

func (s *WorkCalendarConfigList) Schema() []model.Field

type WorkCalendarException

type WorkCalendarException struct {
	Id            string
	TenantId      string
	StaffId       string
	SpecificDate  int64
	ExceptionType string
	StartTime     int64
	EndTime       int64
	Notes         string
}

func ReadOneWorkCalendarException

func ReadOneWorkCalendarException(qb *orm.QB, model *WorkCalendarException) (*WorkCalendarException, error)

func (*WorkCalendarException) DecodeFields

func (m *WorkCalendarException) DecodeFields(r model.FieldReader)

func (*WorkCalendarException) EncodeFields

func (m *WorkCalendarException) EncodeFields(w model.FieldWriter)

func (*WorkCalendarException) IsNil

func (m *WorkCalendarException) IsNil() bool

func (*WorkCalendarException) ModelName

func (m *WorkCalendarException) ModelName() string

func (*WorkCalendarException) Pointers

func (m *WorkCalendarException) Pointers() []any

func (*WorkCalendarException) Schema

func (m *WorkCalendarException) Schema() []model.Field

func (*WorkCalendarException) Validate

func (m *WorkCalendarException) Validate(action byte) error

type WorkCalendarExceptionList

type WorkCalendarExceptionList []*WorkCalendarException

func ReadAllWorkCalendarException

func ReadAllWorkCalendarException(qb *orm.QB) (WorkCalendarExceptionList, error)

func (*WorkCalendarExceptionList) Append

func (*WorkCalendarExceptionList) At

func (*WorkCalendarExceptionList) DecodeFields

func (s *WorkCalendarExceptionList) DecodeFields(_ model.FieldReader)

func (*WorkCalendarExceptionList) EncodeFields

func (s *WorkCalendarExceptionList) EncodeFields(_ model.FieldWriter)

func (*WorkCalendarExceptionList) IsNil

func (s *WorkCalendarExceptionList) IsNil() bool

func (*WorkCalendarExceptionList) Len

func (s *WorkCalendarExceptionList) Len() int

func (*WorkCalendarExceptionList) Pointers

func (s *WorkCalendarExceptionList) Pointers() []any

func (*WorkCalendarExceptionList) Schema

func (s *WorkCalendarExceptionList) Schema() []model.Field

Jump to

Keyboard shortcuts

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