- type: datepicker compiles the D-20 keys; format maps to displayFormat with WinterCMS's momentFormat table
- boot fails when the mode does not match the column's Go type (time.Time, lagoon.Date, lagoon.TimeOfDay)
- datepicker is a writable scalar field; minDate and maxDate are rechecked on save
- columns.yaml accepts type: date and type: time; Scanner/Valuer structs are columns, not relations
- conformance fixture carries date and datetime fields; README, forms and lists docs
- DELETE, PUT and POST reorder under .../{id}/files/{field}, each scoped by one parent query (404 for a foreign file)
- protected download and thumb routes: is_public=false only, nosniff, private no-store, sandbox CSP, inline only for jpeg/png/gif/webp
- the save applies deferred removals, replaces attachOne files and rechecks maxFiles and required
- blobs of deleted files are removed after commit
- swagger2openapi emits binary content for file responses
- admin OpenAPI, TS types, conformance, README and attachments docs
- type: fileupload compiles the D-08 keys and binds to the model's attach.Relation at boot
- X-Session-Key (cabana.SessionKeyHeader) carries the form session key; RecordInput.SessionKey
- GET and POST .../{id}/files/{field}: list with pending uploads, multipart upload into attach.Store
- the create and update save attaches the session's pending files in its transaction
- swagger2openapi folds formData parameters into a multipart requestBody
- admin OpenAPI, TS types, conformance cases, README and forms docs
- Date (DATE) and TimeOfDay (TIME) with Scanner, Valuer, JSON and text forms
- Fill falls back to encoding.TextUnmarshaler for string sources after
every existing conversion, so time.Time and the new types fill from JSON
- required treats a zero time.Time, Date or TimeOfDay as empty
- lagoon README, models and casts-and-validation docs
- deferred_bindings migration set under summercms.deferred with backend_user_id
- lagoon.DeferredBind/Unbind/Bindings/Forget/Slaves scoped by DeferredKey
- lagoon.PurgeDeferred with SKIP LOCKED batches and after-commit blob deletes
- attach.Store with the ported image guard, extension and MIME limits
- attach.Relation, attach.HasRelations, attach.BlobKeys, File.ThumbKey
- lagoon README and attachments docs
PHP 8's (string) cast of a float formats with the precision ini (14
significant digits, %.14G), not the shortest round-trip form: 1/3 is
0.33333333333333, 1e14 is 1.0E+14 and 5e-324 is 4.9406564584125E-324.
phpFloatString, used for the string form of JSON floats in size, in, regex
and integer checks, printed up to 17 digits and switched to the exponent
form only from 1e15. TestPHPFloatStringMatchesPHPCast pins 27 values to
php -r output.
A 162-case truth table recorded from WinterCMS's validator (the vendored
winter/storm Factory, Laravel 9) found three divergences, all on arrays:
- in compared array elements loosely; Laravel uses array_diff, an exact
string comparison, so ["1.0"] is not in 1,2;
- not_in failed when any element was listed; Laravel's validateNotIn is
!validateIn, so an array passes unless every element is listed;
- not_in failed an array without the array rule; Laravel passes it.
validate_rules_test.go keeps the whole table (accepted, array keys,
boolean, numeric, integer, in/not_in, sizes by type, regex, dates and
comparisons, url, presence, nested and map wildcards, bail and order).
A photo whose original is missing, does not decode or declares more than
4096x4096 pixels made attach.File.Thumb return an error, and every listing
that shows the photo answered 500 from then on: one 100-byte PNG uploaded
by any household member broke GET collections and the album for everyone.
Thumb now follows WinterCMS's File::makeThumb catch branch: it logs the
reason at warn level, stores WinterCMS's BrokenImage picture (exported as
attach.BrokenImagePNG) under the thumbnail key and returns its URL. Invalid
arguments, storage errors and encode failures are still errors.
- optional beachcomber.PageSearcher returns a page of candidate ids plus
the engine's found count; beachcomber.SearchPage falls back to
SearchIDs for engines without it, so Engine is unchanged
- Query.QueryByWeights is sent to Typesense as query_by_weights; a
mismatched weight list or a page above typesense.MaxPerPage (250) is
refused before any request
- attach.PublicURL and (*File).URL build Winter File::getPath() URLs; the
thumbnailer decodes webp via golang.org/x/image v0.46.0 and checks the
image size from the header before decoding
- tide requests carry multipart parts (files beside the fixture pinned by
sha256) encoded with the fixed MultipartBoundary, so PHP and Go receive
byte-identical bodies
- tide masks the random partition, disk name and file id of url/thumb_url
upload URLs while still diffing prefix, size, mode and extension, and
NormalizePublications masks Carbon dates in the published album
- lagoon.ValidateRequest ports Laravel 9 request validation: wildcard
expansion, implicit-rule stop, bail, sometimes/nullable/blank skipping,
size messages split by type and character-counted string lengths
- ParseRules, In, CustomRule, UploadedFile and ErrorKeys for rule tables
- pl/en lagoon::validation catalogs ported verbatim from WinterCMS
- lagoon.Validate answers a numeric range failure with the bound that
failed (min, max or numeric between) instead of always max
Add a backend admin migration that creates a unique index on
lower(backend_users.email). Rows copied from WinterCMS may hold emails
that differ only in case, so the migration refuses to run and names the
clashing logins instead of choosing an account to drop.
- lagoon.OrderBy takes variadic lagoon.OrderOption values; lagoon.Collate(name)
emits a validated, double-quoted COLLATE clause (e.g. "pl-x-icu")
- remove the exported CheckLocale and the ICU pl-PL check from Open and Use
- framework test containers and per-test databases are plain PostgreSQL
- lagoon README, root README and docs pages drop the locale requirement;
queries-and-pagination gains a "Sorting with a collation" section
backed by ExampleCollate
- docs/backend: admin controllers, forms, lists and filters, relation
manager, users and permissions, settings, partials and widgets, admin SPA
- docs/services: storage, outbound HTTP, realtime, Web Push, search, parity
testing and the Frontend and AJAX (not provided) page
- Examples for cabana (with testdata/docs YAML), fetchguard, lighthouse and
its centrifugo driver, flare, beachcomber and typesense, tide; lighthouse
and beachcomber TestDocs* regions run on their Postgres harnesses
- concept map rows link their guide pages and the not-provided rows the
Frontend and AJAX page; index lists Backend, Database and Services
- TestDocsRequiredPages asserts the D-08 section order
- docs/database: models, migrations, queries and pagination, relations,
casts and validation, attachments and transactions (lagoon.Transaction,
lagoon.AfterCommit, nested savepoints, lagoon.OnDatabase)
- docs/services: configuration, events, routing with auth groups, rate
limiting, authentication, the OAuth server, mail and localization
- runnable Examples for lagoon, attach, compass, surf, wire, bouncer,
wristband, postcard, phrasebook and festival; lagoon TestDocs* regions
run on the package's Postgres harness through DocsDB
- 15 new required pages
- docs/services/jobs.md: declaring, registering and dispatching jobs, the
summer_jobs record, progress, cancellation and workers
- conga ExampleJob plus dispatch and status regions run by TestDocsDispatch
on the package's Postgres harness (DocsApp in export_docs_test.go)
- concept map links the queued jobs row; services/jobs is a required page
- setup: introduction, installation rewritten from install to serve,
configuration with the keys an application sets
- console: introduction, setup and maintenance, scaffolding, writing
commands, utilities; every command name is checker-verified
- bonfire ExampleCatalog shows arguments, bare and repeatable flags
- index links the section introductions; TestDocsRequiredPages lists
the seven new pages
- docs/setup/coming-from-wintercms.md maps WinterCMS concepts to checked
pkg.Ident spans and lists what SummerCMS does not provide
- party BlogPlugin and ExamplePlugin, shown through src= fences
- TestDocsRequiredPages asserts required pages build as .html and .md
- index links the new page
- src= fences name a file, a Go declaration or Example body, or a docs:start region
- confinement: relative clean paths inside the root, no dotfiles or .env,
no nested go.mod modules, Examples need // Output:, test regions must run
- a drifted or missing snippet is a problem, so docs:build writes nothing
- docs:sync rewrites drifted fence bodies in place
- fences render in figure.code with a source caption; .md fences keep only the language
- bonfire ExampleCall is the first verified example, shown in setup/installation
- lagoon.Transaction doc and README state that a nested call over a root
handle returns an error instead of opening an independent transaction
- beachcomber README no longer promises an immediate sync inside a plain
GORM transaction; it is warned and skipped since 11-08
- TestSyncEngineRegistration: the typesense import registers the driver
and a missing or blank api_key reports Configured false, the gate that
keeps beachcomber from sending anything
- TestCentrifugoRecorder: info/unsubscribe answers, 405 with Allow, 413
above the body cap (not recorded), authorization as a comparison that is
never stored, empty key never authorized, loopback ListenAndServe and
shutdown, waitListening and sleepCtx failures
- TestFlowIDNames: default masked id variables
- TestEngineWire: API key and Accept on every request, create on 404 with
the schema or auto fields, 409 as success, JSONL import with
success:false and unreadable lines as errors (message capped, no
document), 404-tolerant delete/flush with id escaping, SearchIDs
parameters and id parsing, typed errors without bodies, transport
errors without the URL, timeout
- TestEngineConfig: search.typesense.* parsing and the registered engine
(coverage 95.6%)
- beachcomber and lighthouse released their savepoint whenever the inner
function reported no error; a Gate that counts a failed read as off,
or a channel function or delete snapshot that swallows one, left the
caller's Postgres transaction aborted (25P02) and failed the write
- a failed RELEASE now rolls back to the savepoint, as the READMEs promise
- beachcomber gets its testcontainers harness and sync tests
(TestSyncGates, TestSyncAfterCommit, TestSyncDeleteAndSoftDelete,
TestSyncFailuresNonFatal, TestServiceSetup); lighthouse gets
TestBroadcastSwallowedReadFailure