Documentation
¶
Index ¶
- Constants
- Variables
- func NewBusinessHoursView(caller router.Caller, opts ...view.Option) view.Presenter
- func NewClosuresView(caller router.Caller, opts ...view.Option) view.Presenter
- func NewHolidaysView(caller router.Caller, opts ...view.Option) view.Presenter
- type BusinessHours
- func (m *BusinessHours) DecodeFields(r model.FieldReader)
- func (m *BusinessHours) EncodeFields(w model.FieldWriter)
- func (m *BusinessHours) IsNil() bool
- func (m *BusinessHours) Item() model.Item
- func (m *BusinessHours) ModelName() string
- func (m *BusinessHours) Pointers() []any
- func (m *BusinessHours) Schema() []model.Field
- func (m *BusinessHours) Validate(action byte) error
- type BusinessHoursList
- func (s *BusinessHoursList) Append() model.Fielder
- func (s *BusinessHoursList) At(i int) model.Fielder
- func (s *BusinessHoursList) DecodeFields(_ model.FieldReader)
- func (s *BusinessHoursList) EncodeFields(_ model.FieldWriter)
- func (s *BusinessHoursList) IsNil() bool
- func (s *BusinessHoursList) Len() int
- type CalendarChangedPayload
- type ClosedReason
- type Closure
- func (m *Closure) DecodeFields(r model.FieldReader)
- func (m *Closure) EncodeFields(w model.FieldWriter)
- func (m *Closure) IsNil() bool
- func (m *Closure) Item() model.Item
- func (m *Closure) ModelName() string
- func (m *Closure) Pointers() []any
- func (m *Closure) Schema() []model.Field
- func (m *Closure) Validate(action byte) error
- type ClosureList
- type DayDetail
- type Deps
- type GetDayBoundsArgs
- func (m *GetDayBoundsArgs) DecodeFields(r model.FieldReader)
- func (m *GetDayBoundsArgs) EncodeFields(w model.FieldWriter)
- func (m *GetDayBoundsArgs) IsNil() bool
- func (m *GetDayBoundsArgs) ModelName() string
- func (m *GetDayBoundsArgs) Pointers() []any
- func (m *GetDayBoundsArgs) Schema() []model.Field
- func (m *GetDayBoundsArgs) Validate(action byte) error
- type GetDayBoundsArgsList
- func (s *GetDayBoundsArgsList) Append() model.Fielder
- func (s *GetDayBoundsArgsList) At(i int) model.Fielder
- func (s *GetDayBoundsArgsList) DecodeFields(_ model.FieldReader)
- func (s *GetDayBoundsArgsList) EncodeFields(_ model.FieldWriter)
- func (s *GetDayBoundsArgsList) IsNil() bool
- func (s *GetDayBoundsArgsList) Len() int
- type Holiday
- func (m *Holiday) DecodeFields(r model.FieldReader)
- func (m *Holiday) EncodeFields(w model.FieldWriter)
- func (m *Holiday) IsNil() bool
- func (m *Holiday) Item() model.Item
- func (m *Holiday) ModelName() string
- func (m *Holiday) Pointers() []any
- func (m *Holiday) Schema() []model.Field
- func (m *Holiday) Validate(action byte) error
- type HolidayList
- type ListClosuresArgs
- func (m *ListClosuresArgs) DecodeFields(r model.FieldReader)
- func (m *ListClosuresArgs) EncodeFields(w model.FieldWriter)
- func (m *ListClosuresArgs) IsNil() bool
- func (m *ListClosuresArgs) ModelName() string
- func (m *ListClosuresArgs) Pointers() []any
- func (m *ListClosuresArgs) Schema() []model.Field
- func (m *ListClosuresArgs) Validate(action byte) error
- type ListClosuresArgsList
- func (s *ListClosuresArgsList) Append() model.Fielder
- func (s *ListClosuresArgsList) At(i int) model.Fielder
- func (s *ListClosuresArgsList) DecodeFields(_ model.FieldReader)
- func (s *ListClosuresArgsList) EncodeFields(_ model.FieldWriter)
- func (s *ListClosuresArgsList) IsNil() bool
- func (s *ListClosuresArgsList) Len() int
- type ListHolidaysArgs
- func (m *ListHolidaysArgs) DecodeFields(r model.FieldReader)
- func (m *ListHolidaysArgs) EncodeFields(w model.FieldWriter)
- func (m *ListHolidaysArgs) IsNil() bool
- func (m *ListHolidaysArgs) ModelName() string
- func (m *ListHolidaysArgs) Pointers() []any
- func (m *ListHolidaysArgs) Schema() []model.Field
- func (m *ListHolidaysArgs) Validate(action byte) error
- type ListHolidaysArgsList
- func (s *ListHolidaysArgsList) Append() model.Fielder
- func (s *ListHolidaysArgsList) At(i int) model.Fielder
- func (s *ListHolidaysArgsList) DecodeFields(_ model.FieldReader)
- func (s *ListHolidaysArgsList) EncodeFields(_ model.FieldWriter)
- func (s *ListHolidaysArgsList) IsNil() bool
- func (s *ListHolidaysArgsList) Len() int
- type Module
- func (m *Module) AddClosure(c Closure) error
- func (m *Module) AddHoliday(h Holiday) error
- func (m *Module) BankDayAfter(from tinytime.Unix, days int) (tinytime.Unix, error)
- func (m *Module) GetDayBounds(date tinytime.Unix) (tinytime.DayBounds, error)
- func (m *Module) GetDayDetail(date tinytime.Unix) (DayDetail, error)
- func (m *Module) GetWeekdayBounds(dayOfWeek int) (tinytime.DayBounds, error)
- func (m *Module) ListBusinessHours() ([]BusinessHours, error)
- func (m *Module) ListClosures(from, to int64) ([]Closure, error)
- func (m *Module) ListHolidays(from, to int64) ([]Holiday, error)
- func (m *Module) ModelName() string
- func (m *Module) MountOperations(reg router.OperationRegistry)
- func (m *Module) RemoveClosure(id string) error
- func (m *Module) RemoveHoliday(id string) error
- func (m *Module) UpsertBusinessHours(h BusinessHours) error
- type Reader
Constants ¶
const ( ErrNotFound model.NotFound = "business_calendar: record not found" ErrInvalidDay model.Invalid = "business_calendar: day_of_week must be 0..6" ErrInvalidWeekday model.Invalid = "business_calendar: day of week must be 0..6" ErrInvalidMinutes model.Invalid = "business_calendar: minutes must be 0..1439 and open_min < close_min" ErrDuplicateDate model.Conflict = "business_calendar: a record already exists for that date" ErrCannotRead model.Invalid = "business_calendar: cannot read the request" )
domainError is the concrete type of this package's sentinel errors. Code compares them by asserting this type and comparing the value: == between two error values compiles, under TinyGo, to runtime.interfaceEqual, which pulls internal/reflectlite into the wasm binary.
const ( CalendarKindBusinessHours = "BUSINESS_HOURS" CalendarKindHoliday = "HOLIDAY" CalendarKindClosure = "CLOSURE" )
Payload kinds — the ONLY place these literals live. CalendarChangedPayload.Kind carries one of them.
const ( OpListBusinessHours = "list_business_hours" OpUpsertBusinessHours = "upsert_business_hours" OpListHolidays = "list_holidays" OpAddHoliday = "add_holiday" OpRemoveHoliday = "remove_holiday" OpListClosures = "list_closures" OpAddClosure = "add_closure" OpRemoveClosure = "remove_closure" OpGetDayBounds = "get_day_bounds" DescListBusinessHours = "" /* 143-byte string literal not displayed */ DescUpsertBusinessHours = "Crea o cambia el horario de atención de un día de la semana." DescGetDayBounds = "Si el consultorio abre en una fecha y en qué minutos del día, considerando feriados y cierres." DescListHolidays = "Feriados registrados del consultorio." DescAddHoliday = "Registra un feriado: el consultorio no atiende esa fecha." DescRemoveHoliday = "Elimina un feriado registrado." DescListClosures = "Cierres extraordinarios del consultorio (fechas u horas sin atención)." DescAddClosure = "Registra un cierre extraordinario." DescRemoveClosure = "Elimina un cierre extraordinario." )
const ErrNegativeDays = model.Invalid("business_calendar: days must be zero or more")
ErrNegativeDays: BankDayAfter con días negativos.
const EventCalendarChanged = "business.calendar.changed"
EventCalendarChanged fires on every write. appointment_booking subscribes so a professional's editor reflects widened hours without a recompile (CU-03), a new holiday closes the day for everyone (CU-04), and reservations already booked on a day that just became closed are recomputed into conflict. Ejemplo: topic := businesscalendar.EventCalendarChanged
const ModelName = "business_calendar"
ModelName es la identidad de este módulo: mcp.HarvestOps califica cada operación como "business_calendar.<name>" en la red — la calificación que hace que su propio "get_day_bounds" sea distinto de la operación de appointment_booking con el mismo nombre base (la colisión que este mecanismo hace irrepresentable). Los tres constructores NewXView de view.go pasan esta misma constante como view.Ops.Module. Ejemplo: name := cal.ModelName()
Variables ¶
var BusinessHoursModel = model.Definition{ Name: "business_hours", Fields: model.Fields{ {Name: "id", Type: model.Text(), DB: &model.FieldDB{PK: true}}, {Name: "day_of_week", Type: input.Number(), Label: "Day of week", NotNull: true, DB: &model.FieldDB{Unique: true}, Item: model.ItemLabel}, {Name: "open_min", Type: input.Hour(), Label: "Opens at", NotNull: true, Item: model.ItemDescription}, {Name: "close_min", Type: input.Hour(), Label: "Closes at", NotNull: true, Item: model.ItemDescription}, {Name: "is_open", Type: input.Checkbox(), Label: "Open", NotNull: true, Item: model.ItemDescription}, {Name: "notes", Type: input.Textarea(), Label: "Notes", Item: model.ItemDescription}, {Name: "updated_at", Type: model.NanoTime(), NotNull: true}, }, }
BusinessHoursModel: one row per day of week. day_of_week is unique — this module never writes more than seven rows.
Times are MINUTES FROM MIDNIGHT (0..1439), the same encoding appointment_booking uses for work blocks. The archived business_hours module stored clock-time text and forced a conversion at the one boundary that has to compare the two; the encoding is fixed here instead.
Renderable fields use input.* widgets (Storage() unchanged: input.Number() is still FieldInt, input.Checkbox() still FieldBool, input.Textarea() still FieldText) — a plain model.Kind is not a form.Field.Type (see form-codegen skill): crudview.New called form.New(Presenter.Record(), ...) against a record with zero renderable fields and panicked BuildClient for every module in the registry, not just this one. Ejemplo: var bh BusinessHours
var BusinessHours_ = struct { Id string DayOfWeek string OpenMin string CloseMin string IsOpen string Notes string UpdatedAt string }{ Id: "id", DayOfWeek: "day_of_week", OpenMin: "open_min", CloseMin: "close_min", IsOpen: "is_open", Notes: "notes", UpdatedAt: "updated_at", }
var ClosureModel = model.Definition{ Name: "closure", Fields: model.Fields{ {Name: "id", Type: model.Text(), DB: &model.FieldDB{PK: true}}, {Name: "specific_date", Type: input.Number(), Label: "Date", NotNull: true, Item: model.ItemDescription}, {Name: "reason", Type: input.Text(), Label: "Reason", NotNull: true, Item: model.ItemLabel}, {Name: "updated_at", Type: model.NanoTime(), NotNull: true}, }, }
ClosureModel: a dated closure the establishment itself decided (maintenance, an event). Separate from Holiday because the ORIGIN is what the UI shows and what an administrator filters by — collapsing both into one table with a "type" column would make the origin a magic string. Ejemplo: var c Closure
var Closure_ = struct { Id string SpecificDate string Reason string UpdatedAt string }{ Id: "id", SpecificDate: "specific_date", Reason: "reason", UpdatedAt: "updated_at", }
var GetDayBoundsArgsModel = model.Definition{ Name: "get_day_bounds_args", Fields: model.Fields{ {Name: "date", Type: model.Int()}, }, }
Transport-only Args Definitions.
Constraints follow the harness's NotNull semantics: on a base int/bool kind, NotNull rejects the ZERO value (ValidateFields: NotNull && IsZeroPtr), so day_of_week 0 (Sunday), is_open false, or midnight (0 minutes) would be unrepresentable if NotNull were set here. Required ints are therefore enforced as DOMAIN rules in the service (ErrInvalidDay/ErrInvalidMinutes), the single fail-closed chokepoint every write path crosses; NotNull stays only on the text fields where empty is never legal. Ejemplo: var args GetDayBoundsArgs
var HolidayModel = model.Definition{ Name: "holiday", Fields: model.Fields{ {Name: "id", Type: model.Text(), DB: &model.FieldDB{PK: true}}, {Name: "specific_date", Type: input.Number(), Label: "Date", NotNull: true, Item: model.ItemDescription}, {Name: "name", Type: input.Text(), Label: "Name", NotNull: true, Item: model.ItemLabel}, {Name: "notes", Type: input.Textarea(), Label: "Notes"}, {Name: "updated_at", Type: model.NanoTime(), NotNull: true}, }, }
HolidayModel: a dated closure with a legal/administrative origin. Editable at runtime — a holiday that appears by law must never require a recompile. Ejemplo: var h Holiday
var Holiday_ = struct { Id string SpecificDate string Name string Notes string UpdatedAt string }{ Id: "id", SpecificDate: "specific_date", Name: "name", Notes: "notes", UpdatedAt: "updated_at", }
var ListClosuresArgsModel = model.Definition{ Name: "list_closures_args", Fields: model.Fields{ {Name: "from", Type: model.Int()}, {Name: "to", Type: model.Int()}, }, }
Ejemplo: var args ListClosuresArgs
var ListHolidaysArgsModel = model.Definition{ Name: "list_holidays_args", Fields: model.Fields{ {Name: "from", Type: model.Int()}, {Name: "to", Type: model.Int()}, }, }
Ejemplo: var args ListHolidaysArgs
Functions ¶
func NewBusinessHoursView ¶ added in v0.0.2
NewBusinessHoursView construye el Presenter de horas semanales.
func NewClosuresView ¶ added in v0.0.2
NewClosuresView construye el Presenter de cierres.
Types ¶
type BusinessHours ¶ added in v0.0.2
type BusinessHours struct {
Id string
DayOfWeek int64
OpenMin string
CloseMin string
IsOpen bool
Notes string
UpdatedAt time.Nano
}
func ReadOneBusinessHours ¶ added in v0.0.2
func ReadOneBusinessHours(qb *orm.QB, model *BusinessHours) (*BusinessHours, error)
func (*BusinessHours) DecodeFields ¶ added in v0.0.2
func (m *BusinessHours) DecodeFields(r model.FieldReader)
func (*BusinessHours) EncodeFields ¶ added in v0.0.2
func (m *BusinessHours) EncodeFields(w model.FieldWriter)
func (*BusinessHours) IsNil ¶ added in v0.0.2
func (m *BusinessHours) IsNil() bool
func (*BusinessHours) Item ¶ added in v0.0.2
func (m *BusinessHours) Item() model.Item
func (*BusinessHours) ModelName ¶ added in v0.0.2
func (m *BusinessHours) ModelName() string
func (*BusinessHours) Pointers ¶ added in v0.0.2
func (m *BusinessHours) Pointers() []any
func (*BusinessHours) Schema ¶ added in v0.0.2
func (m *BusinessHours) Schema() []model.Field
func (*BusinessHours) Validate ¶ added in v0.0.2
func (m *BusinessHours) Validate(action byte) error
type BusinessHoursList ¶ added in v0.0.2
type BusinessHoursList []*BusinessHours
func ReadAllBusinessHours ¶ added in v0.0.2
func ReadAllBusinessHours(qb *orm.QB) (BusinessHoursList, error)
func (*BusinessHoursList) Append ¶ added in v0.0.2
func (s *BusinessHoursList) Append() model.Fielder
func (*BusinessHoursList) DecodeFields ¶ added in v0.0.2
func (s *BusinessHoursList) DecodeFields(_ model.FieldReader)
func (*BusinessHoursList) EncodeFields ¶ added in v0.0.2
func (s *BusinessHoursList) EncodeFields(_ model.FieldWriter)
func (*BusinessHoursList) IsNil ¶ added in v0.0.2
func (s *BusinessHoursList) IsNil() bool
func (*BusinessHoursList) Len ¶ added in v0.0.2
func (s *BusinessHoursList) Len() int
type CalendarChangedPayload ¶ added in v0.0.2
type CalendarChangedPayload struct {
// FromDate/ToDate bound the affected dates (midnight UTC seconds).
// For a holiday or closure both equal that single date. For a business
// hours change they are 0/0 — a weekly rule has no bounded range, and the
// subscriber must recompute its whole horizon.
FromDate int64
ToDate int64
// Kind names what moved, so a subscriber can skip work it does not care
// about. One of CalendarKindBusinessHours | CalendarKindHoliday |
// CalendarKindClosure.
Kind string
// Closed reports the direction. true when the change CLOSES time (a
// holiday added, hours narrowed) — the only direction that can invalidate
// an existing reservation. false when it opens time, which never does.
Closed bool
}
CalendarChangedPayload says WHAT changed, not merely that something did. A subscriber that only learns "the calendar changed" has to recompute every reservation of every professional; with the range it recomputes a window.
Implements model.Encodable, which events.Event.Payload requires. Ejemplo: var p businesscalendar.CalendarChangedPayload
func (*CalendarChangedPayload) DecodeFields ¶ added in v0.0.2
func (p *CalendarChangedPayload) DecodeFields(r model.FieldReader)
func (*CalendarChangedPayload) EncodeFields ¶ added in v0.0.2
func (p *CalendarChangedPayload) EncodeFields(w model.FieldWriter)
func (*CalendarChangedPayload) IsNil ¶ added in v0.0.2
func (p *CalendarChangedPayload) IsNil() bool
type ClosedReason ¶ added in v0.0.2
type ClosedReason string
ClosedReason nombra el origen de un cierre. Los literales de cadena viven SOLAMENTE en estas constantes — nunca en línea en el lugar de llamada. Ejemplo: var reason businesscalendar.ClosedReason = businesscalendar.ClosedHoliday
const ( ClosedWeekly ClosedReason = "WEEKLY" // business_hours says closed that weekday ClosedHoliday ClosedReason = "HOLIDAY" // a Holiday row falls on that date ClosedLocal ClosedReason = "CLOSURE" // a Closure row falls on that date )
type Closure ¶ added in v0.0.2
func ReadOneClosure ¶ added in v0.0.2
func (*Closure) DecodeFields ¶ added in v0.0.2
func (m *Closure) DecodeFields(r model.FieldReader)
func (*Closure) EncodeFields ¶ added in v0.0.2
func (m *Closure) EncodeFields(w model.FieldWriter)
type ClosureList ¶ added in v0.0.2
type ClosureList []*Closure
func ReadAllClosure ¶ added in v0.0.2
func ReadAllClosure(qb *orm.QB) (ClosureList, error)
func (*ClosureList) Append ¶ added in v0.0.2
func (s *ClosureList) Append() model.Fielder
func (*ClosureList) DecodeFields ¶ added in v0.0.2
func (s *ClosureList) DecodeFields(_ model.FieldReader)
func (*ClosureList) EncodeFields ¶ added in v0.0.2
func (s *ClosureList) EncodeFields(_ model.FieldWriter)
func (*ClosureList) IsNil ¶ added in v0.0.2
func (s *ClosureList) IsNil() bool
func (*ClosureList) Len ¶ added in v0.0.2
func (s *ClosureList) Len() int
type DayDetail ¶ added in v0.0.4
type DayDetail struct {
Bounds tinytime.DayBounds
// ClosedBy nombra por qué el día está cerrado. "" cuando Bounds.Open es true.
ClosedBy ClosedReason
}
DayDetail es la propia respuesta de este módulo para una fecha: los límites neutrales MÁS el por qué un día cerrado está cerrado. ClosedBy es vocabulario de este módulo y nunca cruza a un vecino — vea Reader a continuación.
Es un modelo de resultado solo de salida: implementa model.Encodable para que la operación get_day_bounds pueda responder con él, y nunca es una tabla de BD. Ejemplo: detail, err := cal.GetDayDetail(date)
func (*DayDetail) EncodeFields ¶ added in v0.0.4
func (d *DayDetail) EncodeFields(w model.FieldWriter)
type Deps ¶ added in v0.0.2
type Deps struct {
IDs model.IDGenerator
Publisher events.Publisher
}
Deps lleva los colaboradores inyectados que un módulo nunca debe construir por sí mismo. IDs es obligatorio; Publisher es opcional — nil deshabilita la publicación de eventos de forma silenciosa (no-op). Ejemplo: deps := businesscalendar.Deps{IDs: ids, Publisher: pub}
type GetDayBoundsArgs ¶ added in v0.0.2
type GetDayBoundsArgs struct {
Date int64
}
func (*GetDayBoundsArgs) DecodeFields ¶ added in v0.0.2
func (m *GetDayBoundsArgs) DecodeFields(r model.FieldReader)
func (*GetDayBoundsArgs) EncodeFields ¶ added in v0.0.2
func (m *GetDayBoundsArgs) EncodeFields(w model.FieldWriter)
func (*GetDayBoundsArgs) IsNil ¶ added in v0.0.2
func (m *GetDayBoundsArgs) IsNil() bool
func (*GetDayBoundsArgs) ModelName ¶ added in v0.0.2
func (m *GetDayBoundsArgs) ModelName() string
func (*GetDayBoundsArgs) Pointers ¶ added in v0.0.2
func (m *GetDayBoundsArgs) Pointers() []any
func (*GetDayBoundsArgs) Schema ¶ added in v0.0.2
func (m *GetDayBoundsArgs) Schema() []model.Field
func (*GetDayBoundsArgs) Validate ¶ added in v0.0.2
func (m *GetDayBoundsArgs) Validate(action byte) error
type GetDayBoundsArgsList ¶ added in v0.0.2
type GetDayBoundsArgsList []*GetDayBoundsArgs
func (*GetDayBoundsArgsList) Append ¶ added in v0.0.2
func (s *GetDayBoundsArgsList) Append() model.Fielder
func (*GetDayBoundsArgsList) At ¶ added in v0.0.2
func (s *GetDayBoundsArgsList) At(i int) model.Fielder
func (*GetDayBoundsArgsList) DecodeFields ¶ added in v0.0.2
func (s *GetDayBoundsArgsList) DecodeFields(_ model.FieldReader)
func (*GetDayBoundsArgsList) EncodeFields ¶ added in v0.0.2
func (s *GetDayBoundsArgsList) EncodeFields(_ model.FieldWriter)
func (*GetDayBoundsArgsList) IsNil ¶ added in v0.0.2
func (s *GetDayBoundsArgsList) IsNil() bool
func (*GetDayBoundsArgsList) Len ¶ added in v0.0.2
func (s *GetDayBoundsArgsList) Len() int
type Holiday ¶ added in v0.0.2
func ReadOneHoliday ¶ added in v0.0.2
func (*Holiday) DecodeFields ¶ added in v0.0.2
func (m *Holiday) DecodeFields(r model.FieldReader)
func (*Holiday) EncodeFields ¶ added in v0.0.2
func (m *Holiday) EncodeFields(w model.FieldWriter)
type HolidayList ¶ added in v0.0.2
type HolidayList []*Holiday
func ReadAllHoliday ¶ added in v0.0.2
func ReadAllHoliday(qb *orm.QB) (HolidayList, error)
func (*HolidayList) Append ¶ added in v0.0.2
func (s *HolidayList) Append() model.Fielder
func (*HolidayList) DecodeFields ¶ added in v0.0.2
func (s *HolidayList) DecodeFields(_ model.FieldReader)
func (*HolidayList) EncodeFields ¶ added in v0.0.2
func (s *HolidayList) EncodeFields(_ model.FieldWriter)
func (*HolidayList) IsNil ¶ added in v0.0.2
func (s *HolidayList) IsNil() bool
func (*HolidayList) Len ¶ added in v0.0.2
func (s *HolidayList) Len() int
type ListClosuresArgs ¶ added in v0.0.2
func (*ListClosuresArgs) DecodeFields ¶ added in v0.0.2
func (m *ListClosuresArgs) DecodeFields(r model.FieldReader)
func (*ListClosuresArgs) EncodeFields ¶ added in v0.0.2
func (m *ListClosuresArgs) EncodeFields(w model.FieldWriter)
func (*ListClosuresArgs) IsNil ¶ added in v0.0.2
func (m *ListClosuresArgs) IsNil() bool
func (*ListClosuresArgs) ModelName ¶ added in v0.0.2
func (m *ListClosuresArgs) ModelName() string
func (*ListClosuresArgs) Pointers ¶ added in v0.0.2
func (m *ListClosuresArgs) Pointers() []any
func (*ListClosuresArgs) Schema ¶ added in v0.0.2
func (m *ListClosuresArgs) Schema() []model.Field
func (*ListClosuresArgs) Validate ¶ added in v0.0.2
func (m *ListClosuresArgs) Validate(action byte) error
type ListClosuresArgsList ¶ added in v0.0.2
type ListClosuresArgsList []*ListClosuresArgs
func (*ListClosuresArgsList) Append ¶ added in v0.0.2
func (s *ListClosuresArgsList) Append() model.Fielder
func (*ListClosuresArgsList) At ¶ added in v0.0.2
func (s *ListClosuresArgsList) At(i int) model.Fielder
func (*ListClosuresArgsList) DecodeFields ¶ added in v0.0.2
func (s *ListClosuresArgsList) DecodeFields(_ model.FieldReader)
func (*ListClosuresArgsList) EncodeFields ¶ added in v0.0.2
func (s *ListClosuresArgsList) EncodeFields(_ model.FieldWriter)
func (*ListClosuresArgsList) IsNil ¶ added in v0.0.2
func (s *ListClosuresArgsList) IsNil() bool
func (*ListClosuresArgsList) Len ¶ added in v0.0.2
func (s *ListClosuresArgsList) Len() int
type ListHolidaysArgs ¶ added in v0.0.2
func (*ListHolidaysArgs) DecodeFields ¶ added in v0.0.2
func (m *ListHolidaysArgs) DecodeFields(r model.FieldReader)
func (*ListHolidaysArgs) EncodeFields ¶ added in v0.0.2
func (m *ListHolidaysArgs) EncodeFields(w model.FieldWriter)
func (*ListHolidaysArgs) IsNil ¶ added in v0.0.2
func (m *ListHolidaysArgs) IsNil() bool
func (*ListHolidaysArgs) ModelName ¶ added in v0.0.2
func (m *ListHolidaysArgs) ModelName() string
func (*ListHolidaysArgs) Pointers ¶ added in v0.0.2
func (m *ListHolidaysArgs) Pointers() []any
func (*ListHolidaysArgs) Schema ¶ added in v0.0.2
func (m *ListHolidaysArgs) Schema() []model.Field
func (*ListHolidaysArgs) Validate ¶ added in v0.0.2
func (m *ListHolidaysArgs) Validate(action byte) error
type ListHolidaysArgsList ¶ added in v0.0.2
type ListHolidaysArgsList []*ListHolidaysArgs
func (*ListHolidaysArgsList) Append ¶ added in v0.0.2
func (s *ListHolidaysArgsList) Append() model.Fielder
func (*ListHolidaysArgsList) At ¶ added in v0.0.2
func (s *ListHolidaysArgsList) At(i int) model.Fielder
func (*ListHolidaysArgsList) DecodeFields ¶ added in v0.0.2
func (s *ListHolidaysArgsList) DecodeFields(_ model.FieldReader)
func (*ListHolidaysArgsList) EncodeFields ¶ added in v0.0.2
func (s *ListHolidaysArgsList) EncodeFields(_ model.FieldWriter)
func (*ListHolidaysArgsList) IsNil ¶ added in v0.0.2
func (s *ListHolidaysArgsList) IsNil() bool
func (*ListHolidaysArgsList) Len ¶ added in v0.0.2
func (s *ListHolidaysArgsList) Len() int
type Module ¶ added in v0.0.2
type Module struct {
// contains filtered or unexported fields
}
Module representa el módulo de dominio de horas y feriados. Ejemplo: var m *businesscalendar.Module = cal
func New ¶
New conecta el módulo a un *orm.DB ya conectado; se asume que el esquema ya existe — consulte el subpaquete migrate. Ejemplo: cal, err := businesscalendar.New(db, deps)
func (*Module) AddClosure ¶ added in v0.0.2
AddClosure registra un cierre fechado que el propio establecimiento decidió (mantenimiento, un evento). Las fechas del mismo tipo son únicas, por lo que un segundo cierre en una fecha ya cerrada por cierre es rechazado con ErrDuplicateDate. Ejemplo: err := cal.AddClosure(c)
func (*Module) AddHoliday ¶ added in v0.0.2
AddHoliday registra un cierre fechado legal/administrativo. Una segunda fila en la misma fecha es rechazada (ErrDuplicateDate) — un feriado duplicado cerraría dos veces un día y haría que RemoveHoliday parezca roto. Ejemplo: err := cal.AddHoliday(h)
func (*Module) BankDayAfter ¶ added in v0.5.0
BankDayAfter devuelve la medianoche UTC del día hábil bancario que está days días hábiles después de from. Día hábil bancario: lunes a viernes que no es feriado legal (Holiday). El horario y los cierres propios del establecimiento no cuentan. days == 0 devuelve el mismo día si es hábil, si no el siguiente hábil. Ejemplo: deposito, err := cal.BankDayAfter(cobradoEl, 2) // cobro del viernes con abono a 2 días → martes
func (*Module) GetDayBounds ¶ added in v0.0.2
GetDayBounds es el puerto Reader: solo los límites neutrales, sin ninguna razón adjunta. Satisface estructuralmente cualquier interfaz propia con forma de BoundsReader de un hermano. Ejemplo: bounds, err := cal.GetDayBounds(date)
func (*Module) GetDayDetail ¶ added in v0.0.4
func (*Module) GetWeekdayBounds ¶ added in v0.4.45
GetWeekdayBounds devuelve las horas regulares de un día de la semana (0 = domingo … 6 = sábado) — la plantilla semanal, sin feriados o cierres locales. Vea Reader para saber cuándo usarlo en lugar de GetDayBounds. Ejemplo: bounds, err := cal.GetWeekdayBounds(1)
func (*Module) ListBusinessHours ¶ added in v0.0.2
func (m *Module) ListBusinessHours() ([]BusinessHours, error)
ListBusinessHours devuelve las siete reglas de días de la semana ordenadas por day_of_week. Una semana vacía es un estado válido (cerrada por defecto), no un error. Ejemplo: rows, err := cal.ListBusinessHours()
func (*Module) ListClosures ¶ added in v0.0.2
ListClosures devuelve cierres en el rango [from, to] (segundos UTC a medianoche, inclusivo). Un from/to en cero significa sin límite en esa dirección. Ejemplo: rows, err := cal.ListClosures(0, 0)
func (*Module) ListHolidays ¶ added in v0.0.2
ListHolidays devuelve feriados en el rango [from, to] (segundos UTC a medianoche, inclusivo). Un from/to en cero significa sin límite en esa dirección. Ejemplo: rows, err := cal.ListHolidays(0, 0)
func (*Module) MountOperations ¶ added in v0.0.2
func (m *Module) MountOperations(reg router.OperationRegistry)
func (*Module) RemoveClosure ¶ added in v0.0.2
RemoveClosure elimina un cierre por id. Ejemplo: err := cal.RemoveClosure(id)
func (*Module) RemoveHoliday ¶ added in v0.0.2
RemoveHoliday elimina un feriado por id y reabre su día para reservas. Ejemplo: err := cal.RemoveHoliday(id)
func (*Module) UpsertBusinessHours ¶ added in v0.0.2
func (m *Module) UpsertBusinessHours(h BusinessHours) error
UpsertBusinessHours crea o actualiza la regla semanal para un día de la semana. Una fila nueva nunca puede invalidar la disponibilidad existente (el día no tenía horario antes, por lo que ya estaba cerrado por defecto), por lo que una creación publica Closed: false; solo una actualización que reduce la ventana publica Closed: true. Ejemplo: err := cal.UpsertBusinessHours(bh)
type Reader ¶ added in v0.0.2
type Reader interface {
// GetDayBounds responde "si el establecimiento está abierto en esta fecha, y
// entre qué minutos". date es la medianoche UTC en segundos.
GetDayBounds(date tinytime.Unix) (tinytime.DayBounds, error)
// GetWeekdayBounds responde "entre qué minutos trabaja normalmente el establecimiento
// en este día de la semana" (0 = domingo … 6 = sábado) — solo la plantilla
// semanal: los feriados y cierres locales son excepciones de fecha y NO se
// aplican aquí (GetDayBounds los aplica). Un consumidor que valida un horario
// semanal usa esto; uno que valida una fecha concreta usa GetDayBounds.
//
// Un día de la semana sin fila business_hours, o con is_open == false, está cerrado
// (cerrado por defecto, misma regla que el paso 3 de GetDayDetail).
GetWeekdayBounds(dayOfWeek int) (tinytime.DayBounds, error)
}
Reader es el puerto DE SOLO LECTURA del que dependen los propios consumidores de este módulo — un alias de conveniencia, no el contrato que nombra un módulo de dominio hermano.
Un vecino que solo necesita saber "si esta fecha es utilizable y entre qué minutos" (ej. veltylabs/appointment_booking) declara su PROPIA interfaz devolviendo tinytime.DayBounds — una hoja neutral que ambos lados ya importan — y este Module la satisface estructuralmente, sin adaptador y sin importación en ninguna dirección. Vea webtyp/docs/AGENDA_DOMAIN_MASTER_PLAN.md §3-bis para entender por qué: un módulo genérico de reservas no debe depender de ningún calendario institucional específico. Ejemplo: var reader businesscalendar.Reader = cal