etalon
7d3140334e
feat: messaging with conversations, rich text, attachments, typing, unread (phase 9)
...
- conversations: dm (unique pair, find-or-create), group (titled), project
(customer-bound); participant-only access
- messages: server-sanitized rich text, attachments referencing uploads
from the generic POST /api/v1/files endpoint (rate limited, MIME sniffed)
- unread counts via aggregation; mark-read pushes readBy receipts
- chat files served only to conversation participants (or uploader)
- @mentions in chat notify the mentioned participant
- typing indicator: client WS event relayed to other participants
- WS targeted delivery (SendTo) + 15s polling fallback
- two-pane messages UI: conversation list with unread badges, composer
(contenteditable + formatting buttons), drag & drop upload, inline image
previews with lightbox, new-conversation dialog with user search
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com >
2026-06-12 20:15:56 +02:00
etalon
70a813edfa
feat: bounty board, task lifecycle, AI work performer flow, notifications (phase 8)
...
- whitelist HTML sanitizer (stdlib tokenizer) with XSS vector tests
- developer board: pool-scoped visibility, customer/search/minBounty/sort
filters, stale-task age badges, competing-claims visibility setting,
saved filters in profile extras
- claims: request/withdraw (developer), approve/decline (consultant) with
notifications to winners and losers; unassign/abandon back to board
- work tracking: start, sanitized comments with @mention notifications,
time logging, submit for review
- review queue + review with per-AC checklist stored on the timeline;
approve writes the immutable bountyAwards row (human assignees only)
- assign-to-AI: §5.2 job submission, HMAC-verified callback endpoint,
idempotent by jobId, artifacts downloaded into GridFS, failure path
keeps the task assigned with timeline + notification
- notifications API + bell with unread badge, dropdown, page, WS toasts
- pages: bounty board, my-tasks kanban, task detail (role-driven actions,
review dialog, AI dialog), review queue, developer pool
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com >
2026-06-12 20:11:05 +02:00
etalon
f87b954f27
feat: atomization pipeline with job queue, atomizer client, WS hub, and board UI (phase 7)
...
- internal/extsvc: circuit breaker (§11.16) + retrying bearer JSON client
- atomizer client: §5.1 contract incl. defensive coefficient normalization
and extension coefficient range (0,2]
- persisted jobs collection: atomic claim, panic recovery, exponential
backoff (max 3), stale-running requeue, shutdown-safe bookkeeping
- subdivide (async 202, atomizing status, re-run replaces unpublished
children after confirm) and extend (sibling task, source budget)
- failure path reverts status and notifies the consultant on final attempt
- PATCH task editing with bounty recompute, budget cascade to descendants
- publish single + bulk; task detail endpoint role-scoped
- coder/websocket hub: multiplexed channels, origin check, 30s heartbeats;
client ws.js with reconnect + 15s polling fallback
- consultant atomization board: tree by root, coefficient sliders with live
per-parent sum indicator, bounty preview, modals, shimmer, atomizer-down
gating via /api/v1/service-health
- fix: tasks external-ref unique index is partial, not sparse (compound
sparse indexed every task through customerId and broke child inserts)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com >
2026-06-12 19:17:09 +02:00
etalon
4e01b64bbd
feat: ticketing sync workers with idempotent import and orphan flagging (phase 6)
...
- task domain model + exhaustive §4.4 status machine tests (single source of truth)
- per-customer polling workers reconciled every 30s from the customers
collection; panic-safe runs; manual sync-now trigger; status provider
for the admin panel
- §5.3 upsert keyed on (system, key, customerId): refreshes content while
status=imported, records upstream_changed timeline + notification after
- attachments cached into GridFS via connector-authorized downloads
- orphaned tickets flagged with timeline + consultant notification, never
deleted; idempotent across polls
- consultant identity from users.extra.ticketingIdentities per system
- notifications store (insert/list/unread-count/mark-read)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com >
2026-06-12 19:03:13 +02:00
etalon
34bf5b5ac2
feat: base UI shell with themes, auth pages, profile, and role navigation (phase 4)
...
- embedded Go templates + vanilla ES-module JS + hand-written CSS, no build step
- exact §10 beige light / dark design tokens, square edges (radius 2px),
system font stack, visible focus rings
- theme toggle persisted to localStorage and the user profile
- login/register/change-password pages wired to the auth API
- profile page: avatar upload (image-sniffed, old file cleanup), bio,
contacts, arbitrary extra key/value fields, optimistic-concurrency 409
- role-based top navigation with placeholders for later-phase areas
- GET /files/{id} with scope-based access (session) or signed token (§5.1)
- security headers incl. CSP without unsafe-inline scripts
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com >
2026-06-12 18:39:38 +02:00
etalon
c1cc781279
feat: authentication with local accounts, sessions, CSRF, RBAC, and OIDC PKCE (phase 3)
...
- argon2id (t=3, m=64MiB, p=2) PHC hashing honoring embedded params
- token-bucket rate limiting (10/15min per IP+email) on login/register
- opaque 32B session tokens in Mongo, 30-day sliding expiry, logout-all
- CSRF double-submit cookie/header on authenticated mutations
- bootstrap admin from env with forced first-login password change
- requireAuth/requireRole middleware with disabled-account enforcement
- OIDC code flow with PKCE: lazy discovery, account linking only on
verified email, auto-created developer accounts
- unit tests (RBAC matrix, CSRF, password, rate limiter) + integration
suite covering the full auth matrix incl. an in-test fake IdP
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com >
2026-06-12 18:31:25 +02:00
etalon
f2c534f636
feat: store layer with indexes, optimistic concurrency, GridFS, credential crypto (phase 2)
...
- mongo-driver v2 connection with bounded startup retry + /readyz gate
- idempotent creation of all §4.9 indexes
- UpdateVersioned: version-filtered updates, conflict vs not-found errors
- AES-256-GCM Seal/Open for ticketing credentials, base64(nonce|ct)
- GridFS file store: MIME sniffing, MAX_UPLOAD_MB cap, sha256 metadata
- HMAC-signed short-lived file URL tokens (§5.1, 1h TTL)
- integration tests against compose Mongo via docker-compose.test.yml overlay
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com >
2026-06-12 18:17:26 +02:00
etalon
976f5238f8
feat: scaffold app skeleton with config, ULID, health endpoints, compose stack (phase 1)
...
- internal .env loader (real env wins) + strictly validated config struct
- ULID package: 48-bit ms timestamp + 80-bit crypto randomness, sortable
- HTTP server with recovery/request-id/trusted-proxy/access-log middleware
- /healthz, /readyz (pluggable checkers), /metricsz (counter registry)
- multi-stage Dockerfile (alpine, non-root) + compose with healthchecks,
app bound to 127.0.0.1:8787, mongo unpublished, graceful 15s shutdown
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com >
2026-06-12 18:10:30 +02:00