ParentRowCustomizer and AttachmentPreviewCustomizer read the parent of
every child row to decide whether the row is visible, so rows that share a
parent repeated the same read: 61 tasks on two parents ran 61 parent reads
(TagLookupStatementBudgetTest), now 2. The answer is kept only for the one
postQuery call, where the session and transaction cannot change.
Also correct the README: the Tags field is selectable.
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Core selects the Tags virtual field for every query or get that names no
fields, so every such read of a TAGS-enabled table ran one
collaboration_record_tag statement, including reads made one record at a
time and tables that were never tagged. Measured with 600 added parents
(TagLookupStatementBudgetTest): a 602-row list ran 2 statements, 600 gets
ran 600 and 100 single-record updates ran 100; now 1 probe, then 0.
TaggedTables remembers, per node and per table, whether any assignment
exists (core Memoization registered with ClusterCaches, 30 s by default,
withTagLookupCacheSeconds, 0 disables). Writing an assignment clears it at
once and after commit and publishes memo-invalidate. The probe ignores row
locks and returns no data, so the answer is the same for every session.
Tables with assignments are read as before: one lookup per 500 parents.
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Replace the default-active Core snapshot profile with the released Core
4.1.0-RC.22 BOM, pin qbit-redis to its first release candidate, and replace
the snapshot-era status text with the current 1.0 status.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Verify all 269 Collaboration tests, including PostgreSQL attachment recovery and MySQL/PostgreSQL journals, against the compatible Core snapshot.
Co-Authored-By: GPT-6 Codex <noreply@openai.com>
Save the current implementation and README, status, and known-issue documentation at the user-requested stop. No completed release or deployment is claimed.
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: GPT-6 Codex <noreply@openai.com>
The session uuid is a bearer credential (clients resume sessions with
it as a cookie or bearer token). The first cut kept it on the lease,
replicated it on the internal presence bus and exposed it through a
public leases() accessor.
Derive an opaque session id instead: "s" + the first 16 hex digits of
HMAC-SHA256(secret, sessionUuid), with QQQ_PRESENCE_SESSION_SECRET
(shared across pods) or a random per-process secret. The raw uuid is
dropped at heartbeat; only the opaque id is stored, replicated and
returned (per-connection viewers and presence.changed leases). The
leases() accessor and Lease record are removed. Tests assert the raw
uuid never appears in bus messages, snapshots or HTTP responses.
Refs #54
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Two terminals or tabs of one user collapsed into a single viewer, so
clients could not tell "Admin, twice" from "Admin". The registry
already kept one lease per connection; expose it additively:
- merged viewers carry connections (live leases behind the viewer)
- snapshots and presence.changed carry leaseCount
- GET /presence?perConnection=true adds leases, one viewer per lease
with an opaque connection id, mode, field and lease start;
presence.changed always carries leases (subscribers cannot opt in)
- leases record the server-side session uuid, never sent to clients
- counts() still counts users; connectionCounts() counts leases and
the Who's here card shows both
Extension collaboration 1.2.0; regenerated committed document.
Fixes#54
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Regenerated against UI API 1.6.0: every operation has an operationId and
the standard error responses (BasicErrorResponseV1: error, code, message,
fieldErrors, traceId); the extension's own error schema is kept but
deprecated; hand-written error bodies go through QJavalinUtils so they carry
code/message/traceId. Extension MINOR bumped.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Host-neutral help (deployment-specific facts removed), registered with
HelpBundles, gated by HelpBundleAssertions. QQQ 4.1.0-RC.7.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
CollaborationFollowersProvider implements core RecordFollowersProviderInterface
over collaboration_follow (CHANGE/ALERT -> notifyOnChange, COMMENT ->
notifyOnComment, muted excluded), registered via RecordFeaturesMetaData, so
qbit-alerts can notify followers. Cached favorite/recent labels are stored
only when FieldAccessHelper.isRecordLabelFullAccess holds; notification
titles fall back to the table label and id for recipients without FULL
label access. Timeline masking (MASKED shows the mask, HIDDEN omitted,
canary never leaks) is covered by tests.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Moves the optional email integration from qbit-email internals to
com.kingsrook.qbits.email.api (qbit-email 0.1.0-RC.2) with identical
behaviour, and moves to qbit-build-parent 2.1.1, whose default G1
allow-lists include qbit-email's API (QRun-IO/qbit-bom#12), so the
per-repo allow-lists are gone.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Keeps develop's changes and re-applies the optional qbit-email 0.1.0-RC.1
delivery on top (adapted to develop's refactors; guardrail allow-lists
for the optional integration where the build parent enforces them).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A ?user= request parameter (remembered in the collab_dev_user cookie) chooses the
demo identity for that browser, falling back to -Dcollab.dev.user. The session
now carries values.user (name and email) so the frontend shows Alice Morgan
instead of Anonymous. README documents opening a second browser to see presence.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Replace the HTML wall of text with a KPI block (comments this week, open
threads, open and overdue tasks, open access requests, attachments with a
human-readable size, active custom fields) and full-width Tags, Custom fields
and Who's here tables, each with a real empty state and no hard-coded colors.
Counts still use the caller's session. Tests updated to assert widget data.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Phase (d) of QRun-IO/qbit-email docs/DESIGN.md section 11. qbit-email is an
optional dependency (0.1.0-SNAPSHOT until its first RC) used through one
adapter class behind a classpath and instance guard; without it the
existing behaviour is unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
CollaborationDevServer serves the Next dashboard over an in-memory
instance (people, orders, every record feature on, seeded comments,
files, tags, custom fields, tasks, shares, audit history) with mock users
alice, bob and admin. CustomFieldsProvider now registers generated SELECT
possible value sources on refresh.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
collaboration_field_definition (with DataClassification) and
collaboration_field_value; CustomFieldsProvider contributes ACTIVE fields
through the runtime overlay with JsonPathStorage (Postgres, memory) or a
read-only EAV virtual field elsewhere; Publish/Archive/Rebuild index
actions; the collaborationBuildFieldIndexes job creates expression
indexes CONCURRENTLY (or records the DDL when unmanaged). Presence:
PresenceRegistry replicated over the realtime bus with a 45 s TTL and a
cap, presence.changed events, and POST/DELETE/GET /presence endpoints;
an admin Who's here widget.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Feature settings drive core RecordFeaturesMetaData through
RecordFeatureOverrideProviderInterface; feature permissions come from core
(policy-editor catalog); extension tables declare RecordReferenceTableMetaData
so core enforces parent read access, write rules and mirrored locks; core
cleanup, record-access and summary SPIs are implemented; tags become the
collaborationTags virtual field with a QSubQuery criteria expander (filter,
quick search, #tag) contributed through the runtime overlay; qbit events
publish on the realtime bus. Removes the stand-ins (OtherUserAccess,
UserSessionSupplier, ParentTableRestriction, TagFilterTranslator). Adds
the link, share, access request, task, assignment and My work endpoints.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
parentCommentId lists only its thread (threadId or id = ${input.threadId});
feature settings' scopeName is listed by scopeType (apps or eligible
tables) through FeatureScopeNamePossibleValueProvider; a comment's
fieldName lists the visible fields of its tableName through the reusable
RecordFieldNamePossibleValueProvider. TODOs mark the core dependsOn
switch. One test per pair.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
collaboration_share and collaboration_access_request (requesters see only
table and id; non-readers get a notification without record data);
collaboration_task with reminders and overdue notices, Mark done/Reopen;
collaboration_record_assignment with Assign to / Take ownership bulk
actions; MyWorkService summary (open tasks, records assigned, unread
mentions); home cards; parent cleanup.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
31 spec'd operations over favorites, recents, attachments (multipart
upload; download/preview return a short-lived url), tags, comments,
mentions, follow, timeline and people, with Collaboration* typed schemas,
the committed extension fragment openapi/qqq-v1/collaboration.yaml and a
contract test. Built against QQQ 4.1.0-SNAPSHOT for the extension point
(QRun-IO/qqq#1128); moves to 4.1.0-RC.6 when released.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
collaboration_tag and collaboration_record_tag; FREE or APPROVED_ONLY per
table from feature settings; normalized names, suggestions, usage counts;
Approve, Merge and Delete tags record actions; Add tags / Remove tags bulk
actions for configured host tables; TagFilterTranslator for the filter
operators, to be wrapped in core's criteria expander once QRun-IO/qqq#1140
is released; tag activity on the timeline; the home Tags card.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
collaboration_comment (+ revisions, mentions), collaboration_follow,
collaboration_activity and collaboration_follow_digest tables; comment
threads with markdown bodies, @mentions checked for the recipient's
access, edit history, soft delete and resolve; follow with defaults,
bulk Follow/Unfollow actions and batched change notifications; a
timeline merging audit and activity; a people directory. Notifications go
through a CollaborationNotifier (no-op by default) until the
QAlerts.notify adapter (QRun-IO/qqq#1125) is available.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
collaboration_attachment rows per record, uploads streamed into the
configured bucket with size limits and sha256, presigned downloads and
FILE_PREVIEW previews, a streamed-ETL Delete attachments action, parent
cleanup, the home card, and a parent-access stand-in for core's
record-reference security (QRun-IO/qqq#1138) to be replaced when released.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
collaboration_favorite and collaboration_recent tables locked to their
owner (admin all-access), FavoritesService (star, unstar, list with label
refresh and Unavailable entries, reorder) and RecentsService (throttled
view recording, list, hidden daily trim). Home shows real counts.
UI API endpoints follow once QRun-IO/qqq#1128 is released.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Scaffold per QRun-IO/qqq docs/QRUN-QBIT-REPO-STANDARD.md (CircleCI orb
0.6.8 workflows, release-rc caller, dependabot, wrapper, checkstyle,
community pointer files). First qbit code: CollaborationQBitProducer,
collaboration_feature_setting and collaboration_user tables, the
Collaboration app home with real counts, and the Postgres DDL script.
Design: QRun-IO/qqq#1136.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>