Commit Graph

250 Commits

Author SHA1 Message Date
aleksey e3f5a7ca13 feat(archive): month snapshots on the same node, drop extra-node and HTML /view.
CI / test (push) Failing after 41m15s
CI / deploy-ift (push) Has been skipped
CI / e2e-ift (push) Has been skipped
CI / deploy-stage (push) Has been skipped
CI / e2e-stage (push) Has been skipped
Fixes EventHub/EventHubBack#76

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-17 14:59:30 +03:00
aleksey ef31e7fb40 fix(test): sync migration_engine_tests versions with auth_session_device. Refs EventHub/EventHubBack#74
CI / test (push) Successful in 7m23s
CI / deploy-ift (push) Successful in 3m59s
CI / e2e-ift (push) Successful in 1m29s
CI / deploy-stage (push) Successful in 2m15s
CI / e2e-stage (push) Successful in 4m26s
2026-08-16 18:58:54 +03:00
aleksey 0690020e81 feat(auth): list/revoke sessions with device_name and client_type. Fixes EventHub/EventHubBack#74
CI / test (push) Failing after 10m52s
CI / deploy-ift (push) Has been skipped
CI / e2e-ift (push) Has been skipped
CI / deploy-stage (push) Has been skipped
CI / e2e-stage (push) Has been skipped
2026-08-16 18:30:05 +03:00
aleksey 1c701a5254 fix(share): register calendar_share migration and rebuild old PK schema. Refs EventHub/EventHubBack#73
CI / test (push) Successful in 9m32s
CI / deploy-ift (push) Successful in 4m35s
CI / e2e-ift (push) Successful in 1m40s
CI / deploy-stage (push) Successful in 2m27s
CI / e2e-stage (push) Successful in 4m23s
2026-08-16 10:04:16 +03:00
aleksey fb927b7f71 fix(ci): e2e-stage defaults to *.stage.calentiq.com when secrets empty.
CI / test (push) Successful in 7m31s
CI / deploy-ift (push) Successful in 2m35s
CI / e2e-ift (push) Successful in 2m46s
CI / deploy-stage (push) Successful in 2m33s
CI / e2e-stage (push) Successful in 4m22s
Empty E2E_STAGE_* overrode :-defaults with blank hosts. Refs EventHub/EventHubBack#73
2026-08-16 00:25:12 +03:00
aleksey c1b4897a8b fix(test): use commercial fixtures in logic_search_tests.
CI / test (push) Successful in 7m27s
CI / deploy-ift (push) Successful in 3m30s
CI / e2e-ift (push) Successful in 1m30s
CI / deploy-stage (push) Successful in 2m5s
CI / e2e-stage (push) Failing after 3m22s
Personal is never discoverable; assert exclusion explicitly. Refs EventHub/EventHubBack#73
2026-08-16 00:04:26 +03:00
aleksey fcb737eb47 fix(test): ensure calendar_share table in ACL-related eunit suites.
CI / test (push) Failing after 6m13s
CI / deploy-ift (push) Has been skipped
CI / e2e-ift (push) Has been skipped
CI / deploy-stage (push) Has been skipped
CI / e2e-stage (push) Has been skipped
Harden core_calendar_share get/list when table missing. Refs EventHub/EventHubBack#73
2026-08-15 23:48:12 +03:00
aleksey 331000a464 feat(share): calendar_share invite/ACL for personal and commercial.
CI / test (push) Failing after 6m37s
CI / deploy-ift (push) Has been skipped
CI / e2e-ift (push) Has been skipped
CI / deploy-stage (push) Has been skipped
CI / e2e-stage (push) Has been skipped
Co-editor and deputy grants with mirror_to_default; personal out of search; list owned+shared. Refs EventHub/EventHubBack#73
2026-08-15 23:20:11 +03:00
aleksey 00bf72e4d1 test(notify): prefs gate email/push on reminder and waitlist.
CI / test (push) Successful in 7m47s
CI / deploy-ift (push) Successful in 3m5s
CI / e2e-ift (push) Successful in 1m26s
CI / deploy-stage (push) Successful in 2m13s
CI / e2e-stage (push) Failing after 3m23s
Assert email=false skips SMTP; push=true hits web_push_deliver.
Refs EventHub/EventHubBack#75
2026-08-15 21:50:08 +03:00
aleksey 12274f9ed0 feat(notify): Web Push subscriptions and email/push prefs.
CI / test (push) Successful in 7m43s
CI / deploy-ift (push) Successful in 3m33s
CI / e2e-ift (push) Successful in 1m28s
CI / deploy-stage (push) Failing after 3m40s
CI / e2e-stage (push) Has been skipped
Prefs in user.preferences; push_subscription table; VAPID send on
reminder/waitlist. Refs EventHub/EventHubBack#75
2026-08-15 20:19:44 +03:00
aleksey e86d603f30 fix(email): encode Cyrillic binaries with /utf8.
CI / test (push) Successful in 7m11s
CI / deploy-ift (push) Successful in 3m12s
CI / e2e-ift (push) Successful in 1m26s
CI / deploy-stage (push) Failing after 3m33s
CI / e2e-stage (push) Has been skipped
OTP truncates non-ASCII in <<"...">> to 8-bit bytes, garbling Russian
in mail and in-app notification copy.
2026-08-15 00:32:33 +03:00
aleksey 0a1e55e036 feat(email): HTTP API transport via Resend (fallback SMTP).
CI / test (push) Successful in 7m40s
CI / deploy-ift (push) Successful in 3m29s
CI / e2e-ift (push) Successful in 1m27s
CI / deploy-stage (push) Failing after 3m45s
CI / e2e-stage (push) Has been skipped
Outbound SMTP ports are often blocked on VPS; EMAIL_TRANSPORT=http_api
sends via Resend HTTPS (Brevo optional). OpenSMTPd/SMTP remain available.
2026-08-14 23:54:10 +03:00
aleksey fb8869fa86 feat(waitlist): optional event waitlist with FIFO promote.
CI / test (push) Successful in 7m12s
CI / deploy-ift (push) Successful in 2m44s
CI / e2e-ift (push) Successful in 1m28s
CI / deploy-stage (push) Successful in 2m3s
CI / e2e-stage (push) Successful in 1m24s
Commercial calendars opt in via settings.waitlist_enabled; join when full;
auto-promote on cancel/decline/expire with email and in-app notify.

Refs EventHub/EventHubBack#72
2026-08-14 21:44:42 +03:00
aleksey 29111cd514 feat(upload): avatar and calendar cover via local disk storage.
POST /v1/user/me/avatar and /v1/calendars/:id/cover; GET /v1/media;
UPLOAD_DIR on eventhub-data volume; MIME/size limits.
Refs EventHub/EventHubBack#71
Refs EventHub/EventHubSpec#8
2026-08-14 21:27:34 +03:00
aleksey 15ae8d4426 feat(email): send booking reminders before event start.
Job process_reminders in subscription_worker; REMINDER_LEAD_HOURS window;
CalenTIQ email + in-app event_reminder; idempotent reminder_sent.
Refs EventHub/EventHubBack#70
2026-08-14 20:59:38 +03:00
aleksey 347a645933 feat(auth): POST /v1/logout and admin logout revoke refresh session. Refs EventHub/EventHubBack#69
CI / test (push) Successful in 7m32s
CI / deploy-ift (push) Successful in 2m29s
CI / e2e-ift (push) Successful in 1m29s
CI / deploy-stage (push) Successful in 2m3s
CI / e2e-stage (push) Successful in 2m1s
2026-08-14 20:23:16 +03:00
aleksey 302e1e5e9e chore: ignore local Traefik certs; keep make-traefik-certs.sh. [skip ci] 2026-08-14 19:46:18 +03:00
aleksey 69ee037d45 feat(email): SMTP via gen_smtp and CalenTIQ HTML templates. Refs EventHub/EventHubBack#68 2026-08-14 18:51:09 +03:00
aleksey 3d7ae0d372 fix(api): resolve public calendar GET by unique short_name.
CI / test (push) Successful in 7m28s
CI / deploy-ift (push) Successful in 2m46s
CI / e2e-ift (push) Successful in 1m26s
CI / deploy-stage (push) Successful in 2m4s
CI / e2e-stage (push) Successful in 2m4s
2026-08-14 15:00:41 +03:00
aleksey 658cbda4fe chore(rules): ignore .tmp scratch; IFT e2e needs SMOKE_USER. [skip ci] 2026-08-14 12:52:20 +03:00
aleksey 2567585333 feat(booking): studio journal and instance inbox. Refs EventHub/EventHubFront#60
CI / test (push) Successful in 7m31s
CI / deploy-ift (push) Successful in 2m38s
CI / e2e-ift (push) Successful in 1m26s
CI / deploy-stage (push) Successful in 2m3s
CI / e2e-stage (push) Successful in 1m21s
2026-08-14 11:13:01 +03:00
aleksey 520af23cc6 feat(api): optional auth for public search and studio week. Refs EventHub/EventHubFront#58 2026-08-14 11:02:58 +03:00
aleksey 8a5f254c2a feat(booking): materialize occurrence on POST bookings. Refs EventHub/EventHubBack#67 2026-08-14 10:52:24 +03:00
aleksey e3403f6ed6 fix(ift): ObserverWeb mount at "" so CSS/JS paths are not //css-*
CI / test (push) Successful in 7m23s
CI / deploy-ift (push) Successful in 5m31s
CI / e2e-ift (push) Successful in 1m31s
CI / deploy-stage (push) Successful in 3m16s
CI / e2e-stage (push) Successful in 1m22s
observer_dashboard("/") makes asset href protocol-relative (//css-HASH). Empty path keeps assets at /css-HASH.
2026-08-13 11:27:41 +03:00
aleksey 37011f66a1 fix(ift): mount ObserverWeb dashboard at / on dedicated host
CI / test (push) Successful in 7m42s
CI / deploy-ift (push) Successful in 5m40s
CI / e2e-ift (push) Successful in 1m28s
CI / deploy-stage (push) Successful in 2m12s
CI / e2e-stage (push) Successful in 1m20s
observer.ift.calentiq.com already has its own subdomain; /observer path prefix is redundant.
2026-08-13 10:54:19 +03:00
aleksey c89d08968d fix(test): drop redundant user.email index setup
CI / test (push) Successful in 7m8s
CI / deploy-ift (push) Successful in 2m53s
CI / e2e-ift (push) Successful in 12m1s
CI / deploy-stage (push) Successful in 2m18s
CI / e2e-stage (push) Successful in 1m18s
ensure_tables already adds the email index; a second add_table_index
aborted with {already_exists,user,3} and failed the suite setup.
2026-08-04 10:46:32 +03:00
aleksey 72bc440049 fix(test): add mnesia secondary indexes in eh_test_support
CI / test (push) Failing after 9m25s
CI / deploy-ift (push) Has been skipped
CI / e2e-ift (push) Has been skipped
CI / deploy-stage (push) Has been skipped
CI / e2e-stage (push) Has been skipped
EUnit tables must mirror infra_mnesia:create_indices so dirty_index_read
paths in booking/event/search/user do not abort with badarg.
2026-08-04 10:27:58 +03:00
aleksey 6c0775ee5e feat(infra): add TTL cleanup worker for append-only tables
CI / test (push) Failing after 5m58s
CI / deploy-ift (push) Has been skipped
CI / e2e-ift (push) Has been skipped
CI / deploy-stage (push) Has been skipped
CI / e2e-stage (push) Has been skipped
Periodically prune old read notifications, revoked/expired auth sessions,
and admin_audit in chunked transactions; wire under eventhub config.
2026-08-03 22:57:41 +03:00
aleksey 774f58f9ed fix(user): transactional status updates and paginated list_users
Protect status/login/bot writes with transactions, fix abort Reason
shadowing, keep create_bot email_exists, and add list_users/2 pagination.
2026-08-03 22:56:16 +03:00
aleksey d88689f1a3 fix(auth): make auth_session mutations transactional
Wrap create/rotate/revoke paths in mnesia transactions so concurrent
refresh and family revoke stay atomic; align revoke_* specs with errors.
2026-08-03 22:55:52 +03:00
aleksey e3467e7412 perf(mnesia): use secondary indexes in booking, event, search, review
Replace hot-path dirty_match_object scans with dirty_index_read and batch
calendar lookup in search to cut N+1 enrichment cost.
2026-08-03 22:55:50 +03:00
aleksey 104892bdde fix(ci): remove orphan containers before mnesia volume wipe [skip ci]
After Swarm scale=0, shutdown containers can still hold eventhub-data-N;
force-rm holders and retry volume rm so wipe-mnesia-ift does not fail.
2026-08-01 18:50:07 +03:00
aleksey 2b8fc19822 ci: extract wipe-mnesia into standalone workflows [skip ci]
Move IFT/stage Mnesia wipe out of CI pipeline choice so Gitea Actions shows them as separate dispatch workflows.
2026-08-01 18:43:46 +03:00
aleksey 4eb1f326ec feat(ci): add manual wipe-mnesia jobs for IFT/stage [skip ci]
workflow_dispatch only: wipe-mnesia-ift / wipe-mnesia-stage and scripts/ci-full-mnesia-wipe.sh.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-01 18:30:11 +03:00
aleksey 0a5e86c4a0 fix(recurrence): honor BYDAY for weekly RRULE expansion
CI / test (push) Successful in 8m33s
CI / deploy-ift (push) Successful in 3m26s
CI / e2e-ift (push) Successful in 3m44s
CI / deploy-stage (push) Successful in 2m14s
CI / e2e-stage (push) Successful in 1m21s
Expand weekdays in the DTSTART week and advance by Interval weeks from Monday;
add unit coverage for MO/WE/FR and mid-week starts.
2026-08-01 18:17:23 +03:00
aleksey 0e4e886cd4 feat(specialists): owner is non-deletable specialist on commercial create
CI / test (push) Successful in 8m35s
CI / deploy-ift (push) Successful in 21m2s
CI / e2e-ift (push) Successful in 2m3s
CI / deploy-stage (push) Successful in 2m9s
CI / e2e-stage (push) Successful in 1m16s
Bootstrap calendar_specialist for owner (active); DELETE owner → 403;
toggle via status. Fixes solo assign-to-slot. Refs EventHub/EventHubBack#66
2026-08-01 12:18:36 +03:00
aleksey ba1649f344 fix(ct): teardown litter users/calendars after API suites
CI / test (push) Successful in 7m3s
CI / deploy-ift (push) Successful in 3m53s
CI / e2e-ift (push) Successful in 3m34s
CI / deploy-stage (push) Successful in 2m19s
CI / e2e-stage (push) Successful in 1m19s
Track users/calendars created via register_and_login and create_calendar;
soft-delete via admin API in end_per_suite. Skip with CT_KEEP_DATA=1.
Safety-net soft-deletes remaining @test.local users.

Fixes EventHub/EventHubBack#65
2026-07-31 12:21:15 +03:00
aleksey 7d39c004a1 fix(ct): adapt API tests to sole Default personal
CI / test (push) Successful in 8m11s
CI / deploy-ift (push) Successful in 3m30s
CI / e2e-ift (push) Successful in 6m10s
CI / deploy-stage (push) Successful in 3m3s
CI / e2e-stage (push) Successful in 1m15s
Default create_calendar to commercial; reuse existing personal on 409;
assert verify title Default; cover personal_exists / default_calendar.

Refs EventHub/EventHubBack#64
2026-07-30 22:29:52 +03:00
aleksey 10464de3ec feat(calendar): single Default personal with guards and backfill
CI / test (push) Failing after 7m22s
CI / deploy-ift (push) Has been skipped
CI / e2e-ift (push) Has been skipped
CI / deploy-stage (push) Has been skipped
CI / e2e-stage (push) Has been skipped
Ensure title Default; reject second personal and delete/type-change of
the sole personal; migrate extras to commercial or soft-delete.

Refs EventHub/EventHubBack#64
2026-07-30 22:07:15 +03:00
aleksey bb37909ffb fix(events): guard booking_occupancy when booking table missing
CI / test (push) Successful in 6m45s
CI / deploy-ift (push) Successful in 4m5s
CI / e2e-ift (push) Successful in 9m0s
CI / deploy-stage (push) Successful in 2m36s
CI / e2e-stage (push) Successful in 1m18s
Admin eunit suites call event_to_json without Mnesia booking table;
catch list_by_event failures and treat as free.
2026-07-30 15:56:49 +03:00
aleksey edd396dff8 feat(events): add booking_occupancy on event JSON for studio grid
CI / test (push) Failing after 6m23s
CI / deploy-ift (push) Has been skipped
CI / e2e-ift (push) Has been skipped
CI / deploy-stage (push) Has been skipped
CI / e2e-stage (push) Has been skipped
Expose free|pending|confirmed so commercial calendar can aggregate
slots by occupancy without N GET /bookings calls.
2026-07-30 15:33:49 +03:00
aleksey 1fce1aa12d fix(ci): sync migration_engine_tests ALL_VERSIONS with bag migration
CI / test (push) Successful in 8m58s
CI / deploy-ift (push) Successful in 3m30s
CI / e2e-ift (push) Successful in 2m10s
CI / deploy-stage (push) Successful in 2m17s
CI / e2e-stage (push) Successful in 1m15s
test_join_wait timed out waiting for pending 20260730120000_recurrence_exception_bag.

Refs EventHub/EventHubFront#42
2026-07-30 13:27:57 +03:00
aleksey 32d3e7378e fix(event): store multiple recurrence cancel exceptions
CI / test (push) Failing after 10m4s
CI / deploy-ift (push) Has been skipped
CI / e2e-ift (push) Has been cancelled
CI / deploy-stage (push) Has been cancelled
CI / e2e-stage (push) Has been cancelled
Use bag table for recurrence_exception so canceling several WEEKLY occurrences keeps all exceptions (set key was only master_id).

Refs EventHub/EventHubFront#42
2026-07-30 13:07:13 +03:00
aleksey 4986baf006 feat(calendar): validate org defaults in calendar.settings
CI / test (push) Successful in 7m30s
CI / deploy-ift (push) Successful in 3m46s
CI / e2e-ift (push) Successful in 1m28s
CI / deploy-stage (push) Successful in 2m11s
CI / e2e-stage (push) Successful in 1m15s
Documented keys default_location, default_duration_minutes,
default_recurrence; unknown keys (week_patterns) passthrough;
invalid known shape returns 400.

Refs EventHub/EventHubBack#63
2026-07-29 22:50:31 +03:00
aleksey 4c480f1c43 fix(test): lookup banned words via q after batch
CI / test (push) Successful in 6m38s
CI / deploy-ift (push) Successful in 6m53s
CI / e2e-ift (push) Successful in 2m16s
CI / deploy-stage (push) Successful in 2m15s
CI / e2e-stage (push) Successful in 1m17s
Bare GET /banned-words is paginated (limit 50); on dirty IFT the
batch words fall off page 1 and admin_test_banned_words flakes.
Assert via ?q= like the single-add case; same for delete check.
2026-07-29 15:58:41 +03:00
aleksey faf251b11d fix(calendar): persist settings on PUT/POST
CI / test (push) Successful in 7m4s
CI / deploy-ift (push) Successful in 3m21s
CI / e2e-ift (push) Failing after 52s
CI / deploy-stage (push) Has been skipped
CI / e2e-stage (push) Has been skipped
Accept calendar.settings (e.g. week_patterns) in validate_update
and convert_field; apply on create like tags. Unblocks Front#42
pattern save which previously got 200 with empty settings.
2026-07-29 15:00:55 +03:00
aleksey 7e14dbcf8b docs(rules): require run-wsl-sh for CRLF .sh scripts
CI / test (push) Successful in 6m58s
CI / deploy-ift (push) Successful in 2m47s
CI / e2e-ift (push) Failing after 1m26s
CI / deploy-stage (push) Has been skipped
CI / e2e-stage (push) Has been skipped
Cursor Write on Windows often saves CRLF; bare wsl -e bash script.sh
then fails with No such file. Canon is run-wsl-sh.sh (strip CR).
2026-07-29 12:55:01 +03:00
aleksey 76548e578b chore(make): add verification-token target for multi-stand email lookup
make verification-token EMAIL=… STAND=local|dev|ift|stage|calentiq
fetches admin verification token via Admin API. [skip ci]
2026-07-28 22:26:44 +03:00
aleksey bc85f5ab06 fix(ci-reports): chmod a+r on report.tar.gz for nginx read
mktemp leaves 600; nginx worker got 403 Forbidden on download.

[skip ci]
2026-07-28 19:42:14 +03:00
aleksey 3c2c33f83b feat(ci-reports): publish report.tar.gz archive for offline download
Pack HTML report after publish; link archive in run index and CI log.
Add fetch-ci-report.sh helper for agent curl/extract.

[skip ci]
2026-07-28 13:52:01 +03:00